要求不使用CImage类
时间: 2023-10-09 12:04:24 浏览: 57
好的,如果您不想使用CImage类,您可以使用Windows GDI API和文件I/O函数来加载、转换和保存位图文件。以下是一个示例代码,用于将24位位图文件压缩为RLE 8位格式并保存:
```cpp
// 打开位图文件
CFile file(_T("test.bmp"), CFile::modeRead | CFile::typeBinary);
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
file.Read(&bmfh, sizeof(BITMAPFILEHEADER));
file.Read(&bmih, sizeof(BITMAPINFOHEADER));
// 计算行字节数
int rowSize = (bmih.biWidth * 3 + 3) & ~3;
// 分配位图数据缓冲区
BYTE* pBits = new BYTE[rowSize * bmih.biHeight];
file.Read(pBits, rowSize * bmih.biHeight);
// 关闭位图文件
file.Close();
// 创建DC
HDC hDC = ::GetDC(NULL);
HDC hMemDC = CreateCompatibleDC(hDC);
// 创建调色板
RGBQUAD pal[256];
for (int i = 0; i < 256; i++) {
pal[i].rgbBlue = i;
pal[i].rgbGreen = i;
pal[i].rgbRed = i;
}
// 创建位图
BITMAPINFO bmi = { 0 };
bmi.bmiHeader = bmih;
bmi.bmiHeader.biBitCount = 8;
bmi.bmiHeader.biCompression = BI_RLE8;
bmi.bmiHeader.biClrUsed = 256;
bmi.bmiHeader.biSizeImage = rowSize * bmih.biHeight;
bmi.bmiColors[0].rgbRed = 0;
bmi.bmiColors[0].rgbGreen = 0;
bmi.bmiColors[0].rgbBlue = 0;
bmi.bmiColors[0].rgbReserved = 0;
memcpy(&bmi.bmiColors[1], pal, 256 * sizeof(RGBQUAD));
HBITMAP hBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0);
// 绘制位图
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
StretchDIBits(hMemDC, 0, 0, bmih.biWidth, bmih.biHeight, 0, 0, bmih.biWidth, bmih.biHeight, pBits, &bmi, DIB_RGB_COLORS, SRCCOPY);
SelectObject(hMemDC, hOldBitmap);
// 保存位图
CFile outFile(_T("compressed.bmp"), CFile::modeWrite | CFile::modeCreate);
outFile.Write(&bmfh, sizeof(BITMAPFILEHEADER));
outFile.Write(&bmih, sizeof(BITMAPINFOHEADER));
BYTE* pCompressedBits = NULL;
DWORD dwSize = 0;
GetBitmapBits(pBits, bmi.bmiHeader.biSizeImage, &pCompressedBits, &dwSize, BI_RLE8);
outFile.Write(pCompressedBits, dwSize);
outFile.Close();
// 释放资源
delete[] pCompressedBits;
DeleteObject(hBitmap);
DeleteDC(hMemDC);
::ReleaseDC(NULL, hDC);
```
在上述代码中,我们首先打开位图文件并读取位图文件头和信息头。然后,我们计算每行的字节数,并分配位图数据缓冲区。接下来,我们创建一个DC和调色板,并使用CreateDIBSection函数创建一个新的8位位图。然后,我们使用StretchDIBits函数将原始位图绘制到新位图中。最后,我们使用GetBitmapBits函数将位图数据压缩为RLE 8位格式,并将其写入最终的位图文件中。最后,我们释放所有分配的内存。