VC++将位图中保存的图像灰化(附源码)

       我们在屏幕截图时,先要截取整个桌面的图像保存到位图对象中,然后再对位图中的图像进行灰化处理。

VC++将位图中保存的图像灰化(附源码)_第1张图片

       实现灰化的具体做法是,先调用GetDIBits获取位图中每个像素的RGB色块,然后对每个像素的RGB值做灰化处理(每个RGB值都乘以一个系数,完成灰化),然后再调用SetDIBits将灰化后的RGB块设置回位图对象中。相关代码如下所示:

void DoGrayBitmap()
{
	CUIString strLog;

	HDC hDC = GetDC( this->m_hWnd );
	ASSERT( hDC );
	if ( hDC == NULL )
	{
		strLog.Format( _T("[DoGrayBitmap] GetDC失败, GetLastError: %d"), 
			GetLastError() );
		WriteLog( strLog );
		return;
	}

	BITMAP bmp; 
	GetObject( m_hGrayBitmap, sizeof(bmp), &bmp );
	
	UINT *pData = new UINT[bmp.bmWidth * bmp.bmHeight]; 
	if ( pData == NULL )
	{
		int nSize = bmp.bmWidth * bmp.bmHeight;
		strLog.Format( _T("[DoGrayBitmap]pData通过new申请%s字节的内存失败,直接return"), nSize );
		WriteLog( strLog );

		ReleaseDC( this->m_hWnd, hDC );
		return;
	}

	BITMAPINFO bmpInfo; 
	bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
	bmpInfo.bmiHeader.biWidth = bmp.bmWidth; 
	bmpInfo.bmiHeader.biHeight = -bmp.bmHeight; 
	bmpInfo.bmiHeader.biPlanes = 1; 
	bmpInfo.bmiHeader.biCompression = BI_RGB; 
	bmpInfo.bmiHeader.biBitCount = 32; 

	int nRet = GetDIBits( hDC, m_hGrayBitmap, 0, bmp.bmHeight, pData, &bmpInfo, DIB_RGB_COLORS );
	if ( 0 == nRet )
	{
		strLog.Format( _T("[DoGrayBitmap]GetDIBits失败 nRet == 0, GetLastError: %d"), 
			GetLastError() );
		WriteLog( strLog );
	}

	UINT color, r, g, b; 
	for ( int i = 0; i < bmp.bmWidth * bmp.bmHeight; i++ ) 
	{ 
		color = pData[i]; 
		b = ( color << 8 >> 24 ) * 0.6; 
		g = ( color << 16 >> 24 ) * 0.6; 
		r = ( color << 24 >> 24 ) * 0.6; 
		pData[i] = RGB(r, g, b); 
	} 

	// 如果函数成功,那么返回值就是复制的扫描线数;如果函数失败,那么返回值是0。
	nRet = SetDIBits( hDC, m_hGrayBitmap, 0, bmp.bmHeight, pData, &bmpInfo, DIB_RGB_COLORS ); 
	if ( 0 == nRet )
	{
		strLog.Format( _T("[DoGrayBitmap]SetDIBits失败 nRet == 0, GetLastError: %d"), 
			GetLastError() );
		WriteLog( strLog );
	}

	delete []pData;
	pData = NULL;
	ReleaseDC( this->m_hWnd, hDC ); 
}

你可能感兴趣的:(VC++常用功能代码封装,位图,灰化)