检索位图图像的调色板
Retrieving the palette of a bitmap image
我正在通过 GDI 函数 LoadImage 从文件(BMP 类型)加载位图图像,returns 一个 BITMAP 句柄。
我知道如何访问位图位。但是图像的格式是 8BPP,因此被调色了。如何获取调色板条目?
Select 将位图转为 dc 并调用 GetDIBColorTable
。这里可以使用临时内存dc:
RGBQUAD rgb[256] = { 0 };
HDC memdc = CreateCompatibleDC(hdc);
auto oldbmp = SelectObject(memdc, hbitmap);
GetDIBColorTable(memdc, 0, 256, rgb);
SelectObject(memdc, oldbmp);
DeleteDC(memdc);
或者使用GetDIBits
阅读BITMAPINFO
。您必须预留足够的内存来读取颜色 table + 所有字节 + sizeof(BITMAPINFO)
.
颜色 table 将被复制到 BITMAPINFO
-> bmiColors
Gdi+ 是另一种选择。这是 GDI 示例:
int main()
{
HBITMAP hbitmap = (HBITMAP)LoadImage(0, L"source.bmp",
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
if (!hbitmap)
return 0;
BITMAP bm;
GetObject(hbitmap, sizeof(bm), &bm);
int width = bm.bmWidth;
int height = bm.bmHeight;
WORD clrbits = (WORD)(bm.bmPlanes * bm.bmBitsPixel);
if (clrbits == 8) clrbits = 1;
else if (clrbits <= 4) clrbits = 4;
else if (clrbits <= 8) clrbits = 8;
else if (clrbits <= 16) clrbits = 16;
else if (clrbits <= 24) clrbits = 24;
else clrbits = 32;
HDC hdc = GetDC(0);
if(clrbits == 8)
{
RGBQUAD rgb[256] = { 0 };
HDC memdc = CreateCompatibleDC(hdc);
auto oldbmp = SelectObject(memdc, hbitmap);
GetDIBColorTable(memdc, 0, 256, rgb);
SelectObject(memdc, oldbmp);
DeleteDC(memdc);
}
int palette_size = (clrbits < 24) ? sizeof(RGBQUAD) * (1 << clrbits) : 0;
BITMAPINFO* bmpinfo = (BITMAPINFO*)new BYTE[sizeof(BITMAPINFO) + palette_size];
int width_in_bytes = ((width * clrbits + 31) & ~31) / 8;
DWORD size = width_in_bytes * height;
bmpinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo->bmiHeader.biWidth = width;
bmpinfo->bmiHeader.biHeight = height;
bmpinfo->bmiHeader.biPlanes = bm.bmPlanes;
bmpinfo->bmiHeader.biBitCount = bm.bmBitsPixel;
bmpinfo->bmiHeader.biClrUsed = (clrbits < 24) ? (1 << clrbits) : 0;
bmpinfo->bmiHeader.biCompression = BI_RGB;
bmpinfo->bmiHeader.biSizeImage = size;
BYTE* bits = new BYTE[size];
GetDIBits(hdc, hbitmap, 0, height, bits, bmpinfo, 0);
//palette size should be 1024 for 256 color
//it should be stored in `bmpinfo->bmiColors`
delete[]bits;
delete[](BYTE*)bmpinfo;
DeleteObject(hbitmap);
ReleaseDC(0, hdc);
return 0;
}
我正在通过 GDI 函数 LoadImage 从文件(BMP 类型)加载位图图像,returns 一个 BITMAP 句柄。
我知道如何访问位图位。但是图像的格式是 8BPP,因此被调色了。如何获取调色板条目?
Select 将位图转为 dc 并调用 GetDIBColorTable
。这里可以使用临时内存dc:
RGBQUAD rgb[256] = { 0 };
HDC memdc = CreateCompatibleDC(hdc);
auto oldbmp = SelectObject(memdc, hbitmap);
GetDIBColorTable(memdc, 0, 256, rgb);
SelectObject(memdc, oldbmp);
DeleteDC(memdc);
或者使用GetDIBits
阅读BITMAPINFO
。您必须预留足够的内存来读取颜色 table + 所有字节 + sizeof(BITMAPINFO)
.
颜色 table 将被复制到 BITMAPINFO
-> bmiColors
Gdi+ 是另一种选择。这是 GDI 示例:
int main()
{
HBITMAP hbitmap = (HBITMAP)LoadImage(0, L"source.bmp",
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
if (!hbitmap)
return 0;
BITMAP bm;
GetObject(hbitmap, sizeof(bm), &bm);
int width = bm.bmWidth;
int height = bm.bmHeight;
WORD clrbits = (WORD)(bm.bmPlanes * bm.bmBitsPixel);
if (clrbits == 8) clrbits = 1;
else if (clrbits <= 4) clrbits = 4;
else if (clrbits <= 8) clrbits = 8;
else if (clrbits <= 16) clrbits = 16;
else if (clrbits <= 24) clrbits = 24;
else clrbits = 32;
HDC hdc = GetDC(0);
if(clrbits == 8)
{
RGBQUAD rgb[256] = { 0 };
HDC memdc = CreateCompatibleDC(hdc);
auto oldbmp = SelectObject(memdc, hbitmap);
GetDIBColorTable(memdc, 0, 256, rgb);
SelectObject(memdc, oldbmp);
DeleteDC(memdc);
}
int palette_size = (clrbits < 24) ? sizeof(RGBQUAD) * (1 << clrbits) : 0;
BITMAPINFO* bmpinfo = (BITMAPINFO*)new BYTE[sizeof(BITMAPINFO) + palette_size];
int width_in_bytes = ((width * clrbits + 31) & ~31) / 8;
DWORD size = width_in_bytes * height;
bmpinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo->bmiHeader.biWidth = width;
bmpinfo->bmiHeader.biHeight = height;
bmpinfo->bmiHeader.biPlanes = bm.bmPlanes;
bmpinfo->bmiHeader.biBitCount = bm.bmBitsPixel;
bmpinfo->bmiHeader.biClrUsed = (clrbits < 24) ? (1 << clrbits) : 0;
bmpinfo->bmiHeader.biCompression = BI_RGB;
bmpinfo->bmiHeader.biSizeImage = size;
BYTE* bits = new BYTE[size];
GetDIBits(hdc, hbitmap, 0, height, bits, bmpinfo, 0);
//palette size should be 1024 for 256 color
//it should be stored in `bmpinfo->bmiColors`
delete[]bits;
delete[](BYTE*)bmpinfo;
DeleteObject(hbitmap);
ReleaseDC(0, hdc);
return 0;
}