BI_RLE8压缩的bmp图片像素区如何组织的
时间: 2024-02-19 18:59:57 浏览: 144
在BI_RLE8压缩的BMP图片中,像素数据存储在像素区域内。像素区域的大小由文件头中的图像宽度和高度以及每个像素所占用的位数来确定。具体来说,像素区域是由一行一行的像素组成的,每一行的像素数为图像的宽度。每个像素占用8个位(即1个字节),表示该像素的颜色索引值。在BI_RLE8压缩中,相邻的像素值可能相同,因此可以采用一些特殊的压缩算法来减小文件大小。
相关问题
我想使用MFC生成一幅8位的太阳图像,其使用bmp格式,使用BI_RLE8压缩
以下是使用MFC生成一幅8位的太阳图像,其使用bmp格式,使用BI_RLE8压缩的示例代码:
```c++
// 1. 创建一个8位的位图对象
CBitmap bmp;
bmp.CreateBitmap(256, 256, 1, 8, NULL);
// 2. 创建并初始化位图信息头
BITMAPINFO bmpInfo = { 0 };
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = 256;
bmpInfo.bmiHeader.biHeight = 256;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 8;
bmpInfo.bmiHeader.biCompression = BI_RLE8;
bmpInfo.bmiHeader.biSizeImage = 0;
bmpInfo.bmiHeader.biXPelsPerMeter = 0;
bmpInfo.bmiHeader.biYPelsPerMeter = 0;
bmpInfo.bmiHeader.biClrUsed = 0;
bmpInfo.bmiHeader.biClrImportant = 0;
// 3. 获取位图的DC并填充像素
CDC* bmpDC = CDC::FromHandle(::CreateCompatibleDC(NULL));
bmpDC->SelectObject(&bmp);
for (int y = 0; y < 256; y++) {
for (int x = 0; x < 256; x++) {
int r = sqrt(pow(x - 128, 2) + pow(y - 128, 2)); // 计算距离
if (r < 100) {
bmpDC->SetPixel(x, y, RGB(255, 255, 0)); // 太阳的颜色为黄色
} else {
bmpDC->SetPixel(x, y, RGB(0, 0, 0)); // 背景为黑色
}
}
}
// 4. 创建并填充调色板信息
RGBQUAD pal[256];
for (int i = 0; i < 256; i++) {
pal[i].rgbRed = i;
pal[i].rgbGreen = i;
pal[i].rgbBlue = i;
}
// 5. 保存位图到文件
CImage image;
image.Attach((HBITMAP)bmp.Detach());
image.Save(_T("sun.bmp"), Gdiplus::ImageFormatBMP, &bmpInfo, pal);
// 6. 清理资源
bmpDC->DeleteDC();
delete bmpDC;
```
在上述代码中,我们通过创建一个8位的位图对象,然后通过自己填充像素来生成一幅太阳图像。我们使用了一个简单的算法,以太阳的中心为原点,计算每个像素点到中心的距离,如果距离小于100,则将该像素点的颜色设置为黄色,否则将该像素点的颜色设置为黑色。最后,我们创建并填充了调色板信息,将生成的位图保存到文件中,并清理资源。注意,在使用BI_RLE8压缩时,必须提供调色板信息。
用MFC写一段由无压缩形式的bmp格式图片生成压缩格式为BI_RLE8的代码
以下是使用MFC库生成BI_RLE8压缩格式的bmp图片的示例代码:
```cpp
// 定义BITMAPFILEHEADER结构体
typedef struct tagBITMAPFILEHEADER {
WORD bfType; // 位图文件的类型,必须为"BM"格式
DWORD bfSize; // 位图文件的大小,以字节为单位
WORD bfReserved1; // 保留,必须为0
WORD bfReserved2; // 保留,必须为0
DWORD bfOffBits; // 从文件头到位图数据的偏移量,以字节为单位
} BITMAPFILEHEADER;
// 定义BITMAPINFO结构体
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位图信息头
RGBQUAD bmiColors[1]; // 调色板,只有8位图像才有
} BITMAPINFO;
// 生成压缩格式为BI_RLE8的bmp图片
void GenerateRLE8Bmp(const CString& bmpFileName, int bmpWidth, int bmpHeight, const BYTE* bmpData) {
// 打开文件
CFile bmpFile(bmpFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
// 定义文件头
BITMAPFILEHEADER bmpFileHeader;
bmpFileHeader.bfType = 0x4D42; // 位图文件类型
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD) + bmpWidth * bmpHeight; // 文件大小
bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); // 位图数据偏移量
// 写入文件头
bmpFile.Write(&bmpFileHeader, sizeof(BITMAPFILEHEADER));
// 定义位图信息头
BITMAPINFOHEADER bmpInfoHeader;
bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER); // 位图信息头大小
bmpInfoHeader.biWidth = bmpWidth; // 位图宽度
bmpInfoHeader.biHeight = bmpHeight; // 位图高度
bmpInfoHeader.biPlanes = 1; // 位图颜色平面数,必须为1
bmpInfoHeader.biBitCount = 8; // 每个像素的位数,必须为8
bmpInfoHeader.biCompression = BI_RLE8; // 压缩类型,必须为BI_RLE8
bmpInfoHeader.biSizeImage = bmpWidth * bmpHeight; // 位图数据大小,以字节为单位
bmpInfoHeader.biXPelsPerMeter = 0; // 水平分辨率,以像素每米为单位
bmpInfoHeader.biYPelsPerMeter = 0; // 垂直分辨率,以像素每米为单位
bmpInfoHeader.biClrUsed = 256; // 颜色表中实际使用的颜色数
bmpInfoHeader.biClrImportant = 0; // 对图像显示有重要影响的颜色数
// 写入位图信息头
bmpFile.Write(&bmpInfoHeader, sizeof(BITMAPINFOHEADER));
// 定义调色板
RGBQUAD bmpColors[256];
for (int i = 0; i < 256; i++) {
bmpColors[i].rgbBlue = i;
bmpColors[i].rgbGreen = i;
bmpColors[i].rgbRed = i;
bmpColors[i].rgbReserved = 0;
}
// 写入调色板
bmpFile.Write(bmpColors, 256 * sizeof(RGBQUAD));
// 定义压缩后的位图数据
BYTE* rle8Data = new BYTE[bmpWidth * bmpHeight];
BYTE* rle8Ptr = rle8Data;
for (int i = 0; i < bmpHeight; i++) {
BYTE* rowPtr = (BYTE*)bmpData + (bmpHeight - i - 1) * bmpWidth;
int rowSize = bmpWidth;
while (rowSize > 0) {
int count = 1;
BYTE color = *rowPtr;
rowPtr++;
rowSize--;
while (rowSize > 0 && count < 255 && *rowPtr == color) {
count++;
rowPtr++;
rowSize--;
}
*rle8Ptr++ = count;
*rle8Ptr++ = color;
}
*rle8Ptr++ = 0;
*rle8Ptr++ = 0;
}
// 写入位图数据
bmpFile.Write(rle8Data, bmpWidth * bmpHeight);
// 关闭文件
bmpFile.Close();
// 释放内存
delete[] rle8Data;
}
```
调用示例:
```cpp
// 定义位图数据
const int bmpWidth = 320;
const int bmpHeight = 240;
BYTE bmpData[bmpWidth * bmpHeight];
memset(bmpData, 0, bmpWidth * bmpHeight);
for (int i = 0; i < bmpWidth * bmpHeight; i++) {
bmpData[i] = rand() % 256;
}
// 生成压缩格式为BI_RLE8的bmp图片
GenerateRLE8Bmp(_T("test.bmp"), bmpWidth, bmpHeight, bmpData);
```
阅读全文