Drawing an image in grayscale
Posted
by Zafir Anjum
on August 5th, 1998
If the display supports a 256 color palette, then the function creates a grayscale palette from the color information in the DIB and selects and realizes the palette before drawing the image onto the device context. A grayscale color has equal values in its red, green and blue color values. If the display device supports more than 256 colors, then it will not support a palette and palette manipulation will not help us out. In this case, we modify the color table in the DIB instead. We change all the color entries to grayscale before displaying the bitmap.
// DrawGrayScale - Draws a bitmap in gray scale
// pDC - Pointer to target device context
// hDIB - Handle of device-independent bitmap
//
void DrawGrayScale( CDC *pDC, HANDLE hDIB )
{
CPalette pal;
CPalette *pOldPalette;
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
1 << bmInfo.bmiHeader.biBitCount;
// Create the palette if needed
if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && nColors <= 256 )
{
// The device supports a palette and bitmap has color table
// Allocate memory for a palette
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for( int i=0; i < nColors; i++)
{
long lSquareSum = bmInfo.bmiColors[i].rgbRed
* bmInfo.bmiColors[i].rgbRed
+ bmInfo.bmiColors[i].rgbGreen
* bmInfo.bmiColors[i].rgbGreen
+ bmInfo.bmiColors[i].rgbBlue
* bmInfo.bmiColors[i].rgbBlue;
int nGray = (int)sqrt(((double)lSquareSum)/3);
pLP->palPalEntry[i].peRed = nGray;
pLP->palPalEntry[i].peGreen = nGray;
pLP->palPalEntry[i].peBlue = nGray;
pLP->palPalEntry[i].peFlags = 0;
}
pal.CreatePalette( pLP );
delete[] pLP;
// Select the palette
pOldPalette = pDC->SelectPalette(&pal, FALSE);
pDC->RealizePalette();
}
else if((pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) == 0 && nColors <= 256 )
{
// Device does not supports palettes but bitmap has a color table
// Modify the bitmaps color table directly
// Note : This ends up changing the DIB. If that is not acceptable then
// copy the DIB and then change the copy rather than the original
for( int i=0; i < nColors; i++)
{
long lSquareSum = bmInfo.bmiColors[i].rgbRed
* bmInfo.bmiColors[i].rgbRed
+ bmInfo.bmiColors[i].rgbGreen
* bmInfo.bmiColors[i].rgbGreen
+ bmInfo.bmiColors[i].rgbBlue
* bmInfo.bmiColors[i].rgbBlue;
int nGray = (int)sqrt(((double)lSquareSum)/3);
bmInfo.bmiColors[i].rgbRed = nGray;
bmInfo.bmiColors[i].rgbGreen = nGray;
bmInfo.bmiColors[i].rgbBlue = nGray;
}
}
int nWidth = bmInfo.bmiHeader.biWidth;
int nHeight = bmInfo.bmiHeader.biHeight;
// Draw the image
LPVOID lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
::SetDIBitsToDevice(pDC->m_hDC, // hDC
0, // XDest
0, // YDest
nWidth, // nDestWidth
nHeight, // nDestHeight
0, // XSrc
0, // YSrc
0, // nStartScan
nHeight, // nNumScans
lpDIBBits, // lpBits
(LPBITMAPINFO)hDIB, // lpBitsInfo
DIB_RGB_COLORS); // wUsage
pDC->SelectPalette(pOldPalette, FALSE);
}
Comments:
- Want to load any image file - Mukti (2003/12/02)
- 16 bit and 24 bit images - gumber (2003/02/13)
- A few bug - Peter Taran (2002/10/08)
- binarize a gray scale image - greg (2001/03/29)
- Doubt - Yew (2000/11/06)
- 12-bit grayscale bitmap - Jejo Koola (2000/04/17)
- Drawing an BYTE array with scaling and the columns = 4*N problem - Stanislav Koncebovski (2000/01/16)
- Converting single RGB to grayscale - Petr Novotny (1999/03/05)
- Update to cope with 16 and 24 bit images - Guy Gascoigne - Piggford (1998/09/25)

Comments
There are no comments yet. Be the first to comment!