【发布时间】:2013-01-29 07:53:32
【问题描述】:
我有一个创建 32bpp 位图的完美工作代码,我需要更改它以便创建 8bpp 位图。
这是创建 32bpp 位图的一段代码,在其中绘制,然后它创建一个位图文件并将其存储到字节向量中:
// prepare bitmap:
BYTE* bitmap_data = NULL;
HDC hDC = GetDC(NULL);
HDC memHDC = CreateCompatibleDC(hDC);
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = desiredWidth; // desiredWidth is 800
bmi.bmiHeader.biHeight = desiredHeight; // desiredHeight is 202
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = (((desiredWidth * bmi.bmiHeader.biBitCount + 31) & ~31) >> 3) * desiredHeight;
HBITMAP bitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&bitmap_data, NULL, NULL);
ReleaseDC(NULL, hDC);
DeleteDC(hDC);
... // drawing into bitmap
// prepare bitmap file header:
BITMAPFILEHEADER bf;
memset(&bf, 0, sizeof(BITMAPFILEHEADER));
bf.bfType = MAKEWORD('B', 'M');
bf.bfOffBits = sizeof(BITMAPFILEHEADER) + bmi.bmiHeader.biSize;
bf.bfSize = bf.bfOffBits + bmi.bmiHeader.biSizeImage;
// write bitmap file into the vector:
std::vector<BYTE> bitmapData;
bitmapData.insert(bitmapData.end(), (BYTE*)&bf, ((BYTE*)&bf) + sizeof(BITMAPFILEHEADER));
bitmapData.insert(bitmapData.end(), (BYTE*)&bmi.bmiHeader, ((BYTE*)&bmi.bmiHeader) + sizeof(BITMAPINFOHEADER));
bitmapData.insert(bitmapData.end(), bitmap_data, bitmap_data + bmi.bmiHeader.biSizeImage);
然后将向量存储到文件中:
std::ofstream of("picture.bmp", std::ofstream::out | std::ofstream::binary);
of.write((char*)&bitmapData[0], bitmapData.size());
of.close();
这是输出图像:
我尝试过的:
第一步自然是将32 替换为8 在此行中:bmi.bmiHeader.biBitCount = 32; 导致图像填充为纯灰色。然后基于this answer我做了如下修改:
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
改成:
struct BITMAPINFO256 {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
} bmi;
memset(&bmi, 0, sizeof(BITMAPINFO256));
在调用 CreateDIBSection 之前添加了这个循环:
for (UINT i = 0; i < 256; i++) {
bmi.bmiColors[i].rgbRed = i;
bmi.bmiColors[i].rgbGreen = i;
bmi.bmiColors[i].rgbBlue = i;
}
当bmi.bmiHeader被写入向量时,RGBQUAD数组被包括在内:所以sizeof(BITMAPINFO256)表示头部的大小。
新代码 (full code here) 产生以下输出:
为什么新图片是这样的?那里发生了什么事?我错过了什么?
任何帮助将不胜感激。
【问题讨论】:
-
使用调试器并从 2x2 位图开始,这样您就不会迷失在像素中。
-
@HansPassant:如果您看不出发生这种情况的任何原因,您至少能猜到这里可能出现的问题吗?我被困住了,无法真正找出这里出了什么问题。我使用的函数和结构的文档也没有帮助,我也没有找到任何可以从中找到灵感的好的教程。
标签: c++ visual-c++ bitmap gdi bitmapimage