您可以创建调色板 DIB 部分,每像素 8 位和 256 种颜色,并将调色板初始化为灰色阴影 { 0, 0, 0 }, { 1, 1, 1 }, ... { 255, 255, 255 }.
将单个 GDI BitBlt 插入此位图会使您的原始图像变灰。这是代码 sn-p(在 C++、ATL 和 WTL 中 - 但你应该明白)。
CWindowDC DesktopDc(NULL);
CDC BitmapDc;
ATLVERIFY(BitmapDc.CreateCompatibleDC(DesktopDc));
CBitmap Bitmap;
CTempBuffer<BITMAPINFO> pBitmapInfo;
const SIZE_T nBitmapInfoSize = sizeof (BITMAPINFO) + 256 * sizeof (RGBQUAD);
pBitmapInfo.AllocateBytes(nBitmapInfoSize);
ZeroMemory(pBitmapInfo, nBitmapInfoSize);
pBitmapInfo->bmiHeader.biSize = sizeof pBitmapInfo->bmiHeader;
pBitmapInfo->bmiHeader.biWidth = 320;
pBitmapInfo->bmiHeader.biHeight = 240;
pBitmapInfo->bmiHeader.biPlanes = 1;
pBitmapInfo->bmiHeader.biBitCount = 8;
pBitmapInfo->bmiHeader.biCompression = BI_RGB;
pBitmapInfo->bmiHeader.biSizeImage = 240 * 320;
pBitmapInfo->bmiHeader.biClrUsed = 256;
pBitmapInfo->bmiHeader.biClrImportant = 256;
for(SIZE_T nIndex = 0; nIndex < 256; nIndex++)
{
pBitmapInfo->bmiColors[nIndex].rgbRed = (BYTE) nIndex;
pBitmapInfo->bmiColors[nIndex].rgbGreen = (BYTE) nIndex;
pBitmapInfo->bmiColors[nIndex].rgbBlue = (BYTE) nIndex;
}
Bitmap.Attach(CreateDIBSection(DesktopDc, pBitmapInfo, 0, DIB_RGB_COLORS, NULL, 0));
ATLVERIFY(Bitmap);
BitmapDc.SelectBitmap(Bitmap);
////////////////////////////////////////////////
// This is what greys it out:
ATLVERIFY(BitBlt(BitmapDc, 0, 0, 320, 240, DesktopDc, 0, 0, SRCCOPY));
////////////////////////////////////////////////
ATLVERIFY(BitBlt(DesktopDc, 0, 240, 320, 240, BitmapDc, 0, 0, SRCCOPY));