Drawing an image in grayscale


Sometimes a grayscale image can have more impact than a color image. Depending on the situation, you may choose to display the same image in color or in grayscale. The DrawGrayScale() function given below will draw a color image in grayscale. It handles 256 color bitmaps only.

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:



Comments

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

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Thanks to the Internet of Things (IoT), physical assets are turning into participants in real-time global digital markets. The countless types of assets around us will become as easily indexed, searched and traded as any online commodity. While some industries will be tougher to transform than others – those with physical limitations, such as manufacturing, will be harder to digitize – untold economic opportunities exist for growth and advancement. Our research shows this will create a new "Economy …

  • When individual departments procure cloud service for their own use, they usually don't consider the hazardous organization-wide implications. Read this paper to learn best practices for setting up an internal, IT-based cloud brokerage function that service the entire organization. Find out how this approach enables you to retain top-down visibility and control of network security and manage the impact of cloud traffic on your WAN.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date