如何将调色板添加到位图信息
How to add color palette to BITMAPINFO
我有一个函数,可以创建一个bmp
文件并分别写入文件头、信息头和实际像素数据。在这里:
bool SaveBMP(BYTE* Buffer, int width, int height, long paddedsize, LPCTSTR bmpfile)
{
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER info;
memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));
memset(&info, 0, sizeof(BITMAPINFOHEADER));
bmfh.bfType = 0x4d42; // 0x4d42 = 'BM'
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize;
bmfh.bfOffBits = 0x36; // number of bytes to start of bitmap bits
info.biSize = sizeof(BITMAPINFOHEADER);
info.biWidth = width;
info.biHeight = height;
info.biPlanes = 1;
info.biBitCount = 8;
info.biCompression = 0;
info.biSizeImage = 0;
info.biXPelsPerMeter = 0;
info.biYPelsPerMeter = 0;
info.biClrUsed = 256;
info.biClrImportant = 0;
HANDLE file = CreateFile(bmpfile, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
// write file header
unsigned long bwritten;
if (WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER), &bwritten, NULL) == false)
{
CloseHandle(file);
return false;
}
// write infoheader
if (WriteFile(file, &info, sizeof(BITMAPINFOHEADER), &bwritten, NULL) == false)
{
CloseHandle(file);
return false;
}
// write image data
if (WriteFile(file, Buffer, paddedsize, &bwritten, NULL) == false)
{
CloseHandle(file);
return false;
}
// and close file
CloseHandle(file);
return true;
}
但是,我知道我必须为 8 位灰度图像提供调色板,如以下代码所示。
BITMAPINFO* pbmi
for (int i = 0; i<256; i++)
{
pbmi->bmiColors[i].rgbRed = i;
pbmi->bmiColors[i].rgbGreen = i;
pbmi->bmiColors[i].rgbBlue = i;
pbmi->bmiColors[i].rgbReserved = 0;
}
问题是,我不知道如何将我的BITMAPINFOHEADER
连接到BITMAPINFO
。
有没有办法在我当前的代码中使用CreateDIBSection
函数?
我修改了函数,根本没有使用BITMAPINFO
。我用RGBQUAD
来编写调色板。这是解决方案:
bool SaveBMP(BYTE* Buffer, int width, int height, long paddedsize, LPCTSTR bmpfile)
{
const int NUMBER_OF_COLORS = 256;
const int COLOR_PALETTE_SIZE = NUMBER_OF_COLORS * sizeof(RGBQUAD);
const int HEADER_OFFSET = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + COLOR_PALETTE_SIZE;
const int TOTAL_FILE_SIZE = HEADER_OFFSET + paddedsize;
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER info;
RGBQUAD quad[NUMBER_OF_COLORS];
memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));
memset(&info, 0, sizeof(BITMAPINFOHEADER));
// create the color palette
for (int i = 0; i < NUMBER_OF_COLORS; i++)
{
quad[i].rgbBlue = i;
quad[i].rgbGreen = i;
quad[i].rgbRed = i;
quad[i].rgbReserved = 0;
}
// fill the fileheader
bmfh.bfType = 0x4d42; // 0x4d42 = 'BM'
bmfh.bfSize = TOTAL_FILE_SIZE; // Total file size
bmfh.bfReserved1 = 0; // UNUSED
bmfh.bfReserved2 = 0; // UNUSED
bmfh.bfOffBits = HEADER_OFFSET; // Offset to start of pixel data
// fill the infoheader
info.biSize = sizeof(BITMAPINFOHEADER); // Header size (Must be at least 40)
info.biWidth = width; // Image width
info.biHeight = -height; // Image height
info.biPlanes = 1; // MUST BE 1
info.biBitCount = 8; // Bits per pixel (1, 4, 8, 16, 24 or 32)
info.biCompression = 0; // Compression type (BI_RGB = 0, BI_RLE8 = 1, BI_RLE4 = 2 or BI_BITFIELDS = 3)
info.biSizeImage = height * width; // Image size (May be 0 if not compressed)
info.biXPelsPerMeter = 0; // Preferred resolution in pixels per meter
info.biYPelsPerMeter = 0; // Preferred resolution in pixels per meter
info.biClrUsed = NUMBER_OF_COLORS; // Number of entries in the color map that are actually used
info.biClrImportant = 0; // Number of significant colors (All colors = 0)
// open the file to write to
HANDLE file = CreateFile(bmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == NULL)
{
CloseHandle(file);
return false;
}
// write file header
unsigned long bwritten;
if (WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER), &bwritten, NULL) == false)
{
CloseHandle(file);
return false;
}
// write info header
if (WriteFile(file, &info, sizeof(BITMAPINFOHEADER), &bwritten, NULL) == false)
{
CloseHandle(file);
return false;
}
// write palette
if (WriteFile(file, quad, COLOR_PALETTE_SIZE, &bwritten, NULL) == false)
{
CloseHandle(file);
return false;
}
// write image data
if (WriteFile(file, Buffer, paddedsize, &bwritten, NULL) == false)
{
CloseHandle(file);
return false;
}
// close file
CloseHandle(file);
return true;
}
相关文章:
- C / C++ 移位/偏移/向左或向右移动位图?
- 如何在快板的屏幕中显示子位图的绘制?
- CreateDIBSection为同一图像返回不一致的位图位值
- C++ 位图中的 ttc 字体
- 使用 GDI+ 旋转位图,然后转换为 HDC
- 难以从 CImageList 设置菜单项位图
- 如何将位图拉伸到父面板(wxWidgets 自定义)
- 如何使用 freetype2 访问单色位图中的像素状态
- 将位图 (bmp) 转换为具有透明度的 png (Windows c++)
- 安卓工作室 |CPP 文件错误错误: 位图库中对"AndroidBitmap_unlockPixels"的未定义引用
- 位图到垫子/2D 数组
- Gdiplus位图没有Alpha通道
- 如何从路径字符串加载Gdiplus::位图
- 在C++中使用Gdiplus创建透明位图
- 用C++压缩内存中的位图
- C++gdi::内存中的位图到PNG图像
- LoadImage 函数不适用于 ImageMagick 创建的位图图像
- 按调色板信息裁剪 8 位位图
- 创建内存设备背景信息…对于位图,而不是设备(不是显示)
- C++从8位位图构建像素数据,并访问bmiColor表信息