Usted puede crear una sección DIB con paleta, 8 bits por píxel y 256 colores, e inicializar la paleta a tonos de gris {0 , 0, 0}, {1, 1, 1}, ... {255, 255, 255}.
Un único GDI BitBlt
en este mapa de bits grisá su imagen original. Aquí está el fragmento de código (en C++, ATL y WTL, pero debería hacerse una idea).
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));
No sé acerca de la función GDI única que haría eso ni sobre la conversión de paleta, pero la tercera función del enlace que ha mencionado lo hace. Supongo que temes al rendimiento, ¿verdad? – TLama
No se trata solo de rendimiento, estoy buscando una solución más fácil (tal vez mediante la conversión de paleta o algo así). –
El mapa de bits de 32 bits no contiene paleta. – MBo