我做了一些研究,发现一些现有的questions有答案,但我在这里做错了。
这是我的代码:
void CMeetingScheduleAssistantApp::SetBitmapAsGrayScale(HBITMAP hbmp)
{
//converts hbmp to 32-bit grayscale bitmap
//background colour is retained
if (!hbmp)
return;
HDC hdc = ::GetDC(HWND_DESKTOP);
BITMAP bm;
::GetObject(hbmp, sizeof(bm), &bm);
BITMAPINFO bi = { 0 };
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = bm.bmWidth;
bi.bmiHeader.biHeight = bm.bmHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
std::vector<COLORREF> pixels(bm.bmWidth * bm.bmHeight);
GetDIBits(hdc, hbmp, 0, bm.bmHeight, &pixels[0], &bi, DIB_RGB_COLORS);
//assume that the color at (0,0) is the background color
COLORREF background = pixels[0];
for (auto &pixel : pixels)
{
if (pixel != background)
{
pixel = GetRValue(pixel) * 0.299 +
GetGValue(pixel) * 0.587 +
GetBValue(pixel) * 0.144;
}
}
SetDIBits(hdc, hbmp, 0, bm.bmHeight, &pixels[0], &bi, DIB_RGB_COLORS);
::ReleaseDC(HWND_DESKTOP, hdc);
}
应用此选项时,菜单图标如下所示:
这很奇怪!我做错了什么?
我看到this所以我将一位改为GetBValue(pixel) * 0.114
,但没有区别。
答案 0 :(得分:4)
pixel
的类型为COLORREF
,但您只为其分配一个字节,即您只填充蓝色通道。对于灰度图像,您必须为所有通道分配相同的值,即
for (auto &pixel : pixels)
{
if (pixel != background)
{
auto col = GetRValue(pixel) * 0.299 +
GetGValue(pixel) * 0.587 +
GetBValue(pixel) * 0.114;
pixel = RGB(col, col, col);
}
}
P.S。:0.114是正确的值。使用0.144可以产生大于255的值,即每个通道的最大值。