www.pudn.com > BlurBlendmethod.rar > BlurBlendmethod.cpp, change:2004-07-08,size:6316b


 
///////////////////////////////////////////////////////////////////////////// 
// 
// Filter Procedure 
// 
// Blend a RGB color bitmap. Do not work with RGB(555). 
// 
// Process a blur average blending on the source bitmap. It take the all environnent pixels 
// which are attached to the source pixel 
//  
//      1 1 1 
//		1 S 1 
//      1 1 1 
// 
// Then it compute the average of the color region. If (Pixel.Value - Average) is upper  
// to the LevelDelta then the color S is the Average else it does not change 
// Set levelDelta to zero to apply Blur Method to each pixels of the bitmap. 
// 
// A blending matrix is use to set the weight of each pixel in the average computation 
// Change matrix to change the transformation 
//  
//      1 2 1 
//		2 4 2 
//      1 2 1 
// 
// SumColor is the sum of each element. (Sum = 16 in this example) 
// 
// Average computation is made as follow :  
// 
//		For( i = 0 ; i < MatrixElement ; i ++ ) 
//				Average += ( PixelColor[i] * BlendingMatrix[i] ) 
//		Average = Average / SumColor 
// 
// 
// The following matrix is Blur Blending Method : 
//      1 2 1 
//		2 4 2 
//      1 2 1 
// 
// The following matrix is Blur More Blending Method : 
//      1 1 1 
//		1 1 1 
//      1 1 1 
// 
// 
// NOTE : The format of the source bitmap is not changed. 
// NOTE : The code is not optimized for execution but for a good read comprehension 
// NOTE : This procedure do not assum error managment. It is not the subject of this example. 
// 
///////////////////////////////////////////////////////////////////////////// 
// 
// Input  : Source DC 
//			Source Bitmap 
//			Color Delta 
// 
// Output : None 
// return : None  
// 
///////////////////////////////////////////////////////////////////////////// 
// 
// History : 05/2002 Jean-Rémi PINNA (jrpinna@noos.fr) Wrote it.  
// 
///////////////////////////////////////////////////////////////////////////// 
void _FILTER_BlurMethodBlending( HDC hSrcDc, HBITMAP hSrcBmp, BYTE bDeltaMax ) 
{ 
BITMAPINFO	sBmpInfo; 
BYTE *		pBmpBytes;	 
	 
	::memset( &sBmpInfo, 0, sizeof(BITMAPINFO) ); 
 
	BITMAP SrcBmp; 
	::GetObject(hSrcBmp, sizeof(BITMAP), &SrcBmp); 
 
	if( (SrcBmp.bmBitsPixel != 24) && (SrcBmp.bmBitsPixel != 32) ) 
		return; 
 
	sBmpInfo.bmiHeader.biSize			= sizeof(BITMAPINFOHEADER); 
	sBmpInfo.bmiHeader.biWidth			= SrcBmp.bmWidth; 
	sBmpInfo.bmiHeader.biHeight			= SrcBmp.bmHeight; 
	sBmpInfo.bmiHeader.biBitCount		= SrcBmp.bmBitsPixel; 
	sBmpInfo.bmiHeader.biPlanes			= 1; 
	sBmpInfo.bmiHeader.biCompression	= BI_RGB; 
	sBmpInfo.bmiHeader.biSizeImage		= SrcBmp.bmBitsPixel*SrcBmp.bmWidth*SrcBmp.bmHeight/8; 
 
	pBmpBytes = new BYTE[sBmpInfo.bmiHeader.biSizeImage]; 
 
	// Fill the buffer with a copy of the bitmap's bits 
	::GetDIBits( hSrcDc, 
				 hSrcBmp,  
				 0,  
				 sBmpInfo.bmiHeader.biHeight,  
				 pBmpBytes,  
				 &sBmpInfo,  
				 DIB_RGB_COLORS ); 
 
 
	DWORD dwLineWidth, dwByteCount, dwBytesPixel, dwImageSize; 
 
	dwLineWidth		= SrcBmp.bmBitsPixel*SrcBmp.bmWidth/8; 
	dwBytesPixel	= SrcBmp.bmBitsPixel/8; 
	dwImageSize		= sBmpInfo.bmiHeader.biSizeImage; 
	dwByteCount		= dwBytesPixel;	// Start to second pixel to avoid bug on first pixel (Previous bottom point coordinate is 1276) 
 
 
	// Blending Matrix ---- This matrix correspond to the Blur More blending method  
	//						The middle pixel value is the average of all environnent pixels 
	//						Change value of an element modify his weight in the computation of the average 
	// 
	// BYTE bBlurMoreBlendingMatrix[9] = {	1, 1, 1,  
	//										1, 1, 1, 
	//										1, 1, 1 }; 
	// 
	// BYTE bHalfBlendingMatrix[9] = {	0, 1, 0,  
	//									1, 1, 1, 
	//									0, 1, 0 }; 
 
 
	// Blending Matrix ---- This matrix correspond to the Blur blending method  
	//						The sum of the elements of the array must not exceed 256 
	// 
	BYTE bBlurBlendingMatrix[9] = { 1, 2, 1,  
									2, 4, 2, 
									1, 2, 1 }; 
 
 
	// This matrix contain the values to needed to point on corresponding bit 
	// 
	long nPosRange[9]	= {	-(long)(dwLineWidth-dwBytesPixel)	, -(long)(dwLineWidth)	, -(long)(dwLineWidth+dwBytesPixel), 
							-(long)(dwBytesPixel)				, 0						, +dwBytesPixel, 
							+(dwLineWidth-dwBytesPixel)			, +(dwLineWidth)		, +(dwLineWidth+dwBytesPixel) }; 
 
 
	// Sum Blending Matrix Elements 
	// 
	BYTE bMatrixSum = 0; 
 
	for( int iSum = 0 ; iSum<9 ; iSum++ ) 
		bMatrixSum += bBlurBlendingMatrix[iSum]; 
 
	while( dwByteCount < dwImageSize ) 
	{ 
		DWORD bDelta, dwAverage; 
 
		// Create array of pixel's positions 
		// 
		long nPosNewRange[9]= {	(long)(dwByteCount+nPosRange[0]), (long)(dwByteCount+nPosRange[1]), (long)(dwByteCount+nPosRange[2]), 
								(long)(dwByteCount+nPosRange[3]), (long)(dwByteCount+nPosRange[4]), (long)(dwByteCount+nPosRange[5]), 
								(long)(dwByteCount+nPosRange[6]), (long)(dwByteCount+nPosRange[7]), (long)(dwByteCount+nPosRange[8]) }; 
 
		// Check point validity : ensure points are in the bit array 
		// 
		for( int iPos = 0 ; iPos < 9 ; iPos++ ) 
		{ 
			nPosNewRange[iPos] =	nPosNewRange[iPos] < 0 ? 0 :  
									nPosNewRange[iPos] > (long)dwImageSize ? dwByteCount : nPosNewRange[iPos]; 
		} 
		 
		// Compute method on each RGB color of the pixel 
		// 
		for( int iColor = 0 ; iColor < 3 ; iColor++ ) 
		{ 
			dwAverage = 0; 
 
			// Compute Color average 
			// 
			BYTE bColorValue[9] = {	pBmpBytes[nPosNewRange[0]+iColor], pBmpBytes[nPosNewRange[1]+iColor], pBmpBytes[nPosNewRange[2]+iColor],  
									pBmpBytes[nPosNewRange[3]+iColor], pBmpBytes[nPosNewRange[4]+iColor], pBmpBytes[nPosNewRange[5]+iColor],  
									pBmpBytes[nPosNewRange[6]+iColor], pBmpBytes[nPosNewRange[7]+iColor], pBmpBytes[nPosNewRange[8]+iColor] }; 
 
			// Apply Blendind Matrix to compute color average 
			// 
			for( iPos = 0 ; iPos < 9 ; iPos++ ) 
				dwAverage += bColorValue[iPos]*bBlurBlendingMatrix[iPos]; 
 
			BYTE bAverage = (BYTE)(dwAverage/bMatrixSum); 
 
			bDelta = abs( pBmpBytes[dwByteCount]-bAverage ); 
			pBmpBytes[dwByteCount+iColor] = bDelta > bDeltaMax ? bAverage : pBmpBytes[dwByteCount+iColor]; 
		} 
 
		// Move to next pixel 
		// 
		dwByteCount+=dwBytesPixel; 
	} 
 
 
	::SetDIBits( hSrcDc, 
				 hSrcBmp,  
				 0,  
				 sBmpInfo.bmiHeader.biHeight,  
				 pBmpBytes,  
				 &sBmpInfo,  
				 DIB_RGB_COLORS ); 
 
 
	delete pBmpBytes; 
}