www.pudn.com > Image_Manage.rar > FUNCAPI.CPP


 
/************************************************************************** 
 *  文件名:funcapi.cpp 
 * 
 *  图像点运算API函数库: 
 * 
 *  Template()		- 用指定的模板(任意大小)来对图像进行操作 
 *   
 *************************************************************************/ 
 
#include "stdafx.h" 
#include "DIBAPI.H" 
#include "FUNCAPI.H" 
 
#include  
#include  
/************************************************************************* 
 * 
 * 函数名称: 
 *   Template() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits    - 指向源DIB图像指针 
 *   LONG  lWidth       - 源图像宽度(象素数) 
 *   LONG  lHeight      - 源图像高度(象素数) 
 *   int   iTempH		- 模板的高度 
 *   int   iTempW		- 模板的宽度 
 *   int   iTempMX		- 模板的中心元素X坐标 ( < iTempW - 1) 
 *   int   iTempMY		- 模板的中心元素Y坐标 ( < iTempH - 1) 
 *	 FLOAT * fpArray	- 指向模板数组的指针 
 *	 FLOAT fCoef		- 模板系数 
 *	 int   nBitCount	- 像素位数 
 * 
 * 返回值: 
 *   BOOL               - 成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 *   该函数用指定的模板(任意大小)来对图像进行操作,参数iTempH指定模板 
 * 的高度,参数iTempW指定模板的宽度,参数iTempMX和iTempMY指定模板的中心 
 * 元素坐标,参数fpArray指定模板元素,fCoef指定系数。 
 * 
 ************************************************************************/ 
 
BOOL WINAPI Template(LPSTR lpDIBBits, LONG lWidth, LONG lHeight,  
					 int iTempH, int iTempW,  
					 int iTempMX, int iTempMY, 
					 FLOAT * fpArray, FLOAT fCoef, int nBitCount) 
{ 
	// 指向复制图像的指针 
	LPSTR	lpNewDIBBits; 
	HLOCAL	hNewDIBBits; 
	 
	// 指向源图像的指针 
	unsigned char*	lpSrc; 
	 
	// 指向要复制区域的指针 
	unsigned char*	lpDst; 
	 
	// 循环变量 
	LONG	i; 
	LONG	j; 
	LONG	k; 
	LONG	l; 
	int		rgb; 
	 
	// 计算结果 
	FLOAT	fResult; 
	 
	// 图像每行的字节数 
	LONG lLineBytes; 
	 
	// 计算图像每行的字节数 
	switch(nBitCount) 
	{ 
	case 8: 
		lLineBytes = WIDTHBYTES(lWidth * 8); 
		break; 
	case 24: 
		lLineBytes = WIDTHBYTES(lWidth * 24); 
	} 
	 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); 
	 
	// 判断是否内存分配失败 
	if (hNewDIBBits == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits = (char * )LocalLock(hNewDIBBits); 
	 
	// 初始化图像为原始图像 
	memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight); 
 
	switch(nBitCount) 
	{ 
	// 256色图像 
	case 8: 
		// 行(除去边缘几行) 
		for(i = iTempMY; i < lHeight - iTempH + iTempMY + 1; i++) 
		{ 
			// 列(除去边缘几列) 
			for(j = iTempMX; j < lWidth - iTempW + iTempMX + 1; j++) 
			{ 
				// 指向新DIB第i行,第j个象素的指针 
				lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j; 
				 
				fResult = 0; 
				 
				// 计算 
				for (k = 0; k < iTempH; k++) 
				{ 
					for (l = 0; l < iTempW; l++) 
					{ 
						// 指向DIB第i - iTempMY + k行,第j - iTempMX + l个象素的指针 
						lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iTempMY - k) 
							+ j - iTempMX + l; 
						 
						// 保存象素值 
						fResult += (* lpSrc) * fpArray[k * iTempW + l]; 
					} 
				} 
				 
				// 乘上系数 
				fResult *= fCoef; 
				 
				// 取绝对值 
				fResult = (FLOAT ) fabs(fResult); 
				 
				// 判断是否超过255 
				if(fResult > 255) 
				{ 
					// 直接赋值为255 
					* lpDst = 255; 
				} 
				else 
				{ 
					// 赋值 
					* lpDst = (unsigned char) (fResult + 0.5); 
				} 
				 
			} 
		} 
		break; 
	// 真彩色图像 
	case 24: 
		// 行(除去边缘几行) 
		for(i = iTempMY; i < lHeight - iTempH + iTempMY + 1; i++) 
		{ 
			// 列(除去边缘几列) 
			for(j = iTempMX; j < lWidth - iTempW + iTempMX + 1; j++) 
			{ 
				// 分别处理R, G, B 三种颜色 
				for(rgb=0;rgb<3;rgb++) 
				{ 
					// 指向新DIB第i行,第j个象素的指针 
					lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + rgb; 
					 
					fResult = 0; 
					 
					// 计算 
					for (k = 0; k < iTempH; k++) 
					{ 
						for (l = 0; l < iTempW; l++) 
						{ 
							// 指向DIB第i - iTempMY + k行,第j - iTempMX + l个象素的指针 
							lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iTempMY - k) 
								+ (j - iTempMX + l) * 3 +rgb; 
							 
							// 保存象素值 
							fResult += (* lpSrc) * fpArray[k * iTempW + l]; 
						} 
					} 
					 
					// 乘上系数 
					fResult *= fCoef; 
					 
					// 取绝对值 
					fResult = (FLOAT ) fabs(fResult); 
					 
					// 判断是否超过255 
					if(fResult > 255) 
					{ 
						// 直接赋值为255 
						* lpDst = 255; 
					} 
					else 
					{ 
						// 赋值 
						* lpDst = (unsigned char) (fResult + 0.5); 
					} 
				} 
			} 
		} 
		break; 
	} 
	// 复制变换后的图像 
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); 
	 
	// 释放内存 
	LocalUnlock(hNewDIBBits); 
	LocalFree(hNewDIBBits); 
	 
	// 返回 
	return TRUE; 
} 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   GradSharp() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits    - 指向源DIB图像指针 
 *   LONG  lWidth       - 源图像宽度(象素数) 
 *   LONG  lHeight      - 源图像高度(象素数) 
 *   BYTE  bThre		- 阈值 
 *	 int   nBitCount	- 像素位数 
 * 
 * 返回值: 
 *   BOOL               - 成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 *   该函数用来对图像进行梯度锐化。 
 * 
 ************************************************************************/ 
BOOL WINAPI GradSharp(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BYTE bThre, int nBitCount) 
{ 
	 
	// 指向源图像的指针 
	unsigned char*	lpSrc; 
	unsigned char*	lpSrc1; 
	unsigned char*	lpSrc2; 
	 
	// 循环变量 
	LONG	i; 
	LONG	j; 
	int		k; 
	 
	// 图像每行的字节数 
	LONG	lLineBytes; 
	 
	// 中间变量 
	BYTE	bTemp; 
	 
	// 计算图像每行的字节数 
	switch(nBitCount) 
	{ 
	case 8: 
		lLineBytes = WIDTHBYTES(lWidth * 8); 
		// 每行 
		for(i = 0; i < lHeight; i++) 
		{ 
			// 每列 
			for(j = 0; j < lWidth; j++) 
			{ 
				// 指向DIB第i行,第j个象素的指针 
				lpSrc  = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j; 
				 
				// 指向DIB第i+1行,第j个象素的指针 
				lpSrc1 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 2 - i) + j; 
				 
				// 指向DIB第i行,第j+1个象素的指针 
				lpSrc2 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j + 1; 
				 
				bTemp = abs((*lpSrc)-(*lpSrc1)) + abs((*lpSrc)-(*lpSrc2)); 
				 
				// 判断是否小于阈值 
				if (bTemp < 255) 
				{ 
					// 判断是否大于阈值,对于小于情况,灰度值不变。 
					if (bTemp >= bThre) 
					{ 
						// 直接赋值为bTemp 
						*lpSrc = bTemp; 
					} 
				} 
				else 
				{ 
					// 直接赋值为255 
					*lpSrc = 255; 
				} 
			} 
		} 
		break; 
	case 24: 
		lLineBytes = WIDTHBYTES(lWidth * 24); 
		// 每行 
		for(i = 0; i < lHeight - 1; i++) 
		{ 
			// 每列 
			for(j = 0; j < lWidth - 1; j++) 
			{ 
				// 分别对每个像素的R, G, B值进行操作 
				for(k = 0; k < 3; k++) 
				{ 
					// 指向DIB第i行,第j个象素的指针 
					lpSrc  = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + k; 
					 
					// 指向DIB第i+1行,第j个象素的指针 
					lpSrc1 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 2 - i) + j * 3 + k; 
					 
					// 指向DIB第i行,第j+1个象素的指针 
					lpSrc2 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i)  + j * 3 + 3 + k; 
					 
					bTemp = abs((*lpSrc)-(*lpSrc1)) + abs((*lpSrc)-(*lpSrc2)); 
					 
					// 判断是否小于阈值 
					if (bTemp < 255) 
					{ 
						// 判断是否大于阈值,对于小于情况,灰度值不变。 
						if (bTemp >= bThre) 
						{ 
							// 直接赋值为bTemp 
							*lpSrc = bTemp; 
						} 
					} 
					else 
					{ 
						// 直接赋值为255 
						*lpSrc = 255; 
					} 
				} 
			} 
		} 
	} 
	 
	 
	 
	// 返回 
	return TRUE; 
} 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   MedianFilter() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits		- 指向源DIB图像指针 
 *   LONG  lWidth			- 源图像宽度(象素数) 
 *   LONG  lHeight			- 源图像高度(象素数) 
 *   int   iFilterH			- 滤波器的高度 
 *   int   iFilterW			- 滤波器的宽度 
 *   int   iFilterMX		- 滤波器的中心元素X坐标 
 *   int   iFilterMY		- 滤波器的中心元素Y坐标 
 *	 int   nBitCount	- 像素位数 
 * 
 * 返回值: 
 *   BOOL					- 成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 *   该函数对DIB图像进行中值滤波。 
 * 
 ************************************************************************/ 
 
BOOL WINAPI MedianFilter(LPSTR lpDIBBits, LONG lWidth, LONG lHeight,  
						 int iFilterH, int iFilterW,  
						 int iFilterMX, int iFilterMY, int nBitCount) 
{ 
	 
	// 指向源图像的指针 
	unsigned char*	lpSrc; 
	 
	// 指向要复制区域的指针 
	unsigned char*	lpDst; 
	 
	// 指向复制图像的指针 
	LPSTR			lpNewDIBBits; 
	HLOCAL			hNewDIBBits; 
	 
	// 指向滤波器数组的指针 
	unsigned char	* aValue; 
	HLOCAL			hArray; 
	 
	// 循环变量 
	LONG			i; 
	LONG			j; 
	LONG			k; 
	LONG			l; 
	int				rgb; 
	 
	// 图像每行的字节数 
	LONG			lLineBytes; 
	 
	// 计算图像每行的字节数 
	switch(nBitCount) 
	{ 
	case 8: 
		lLineBytes = WIDTHBYTES(lWidth * 8); 
		break; 
	case 24: 
		lLineBytes = WIDTHBYTES(lWidth * 24); 
	} 
	 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); 
	 
	// 判断是否内存分配失败 
	if (hNewDIBBits == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits = (char * )LocalLock(hNewDIBBits); 
	 
	// 初始化图像为原始图像 
	memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight); 
	 
	// 暂时分配内存,以保存滤波器数组 
	hArray = LocalAlloc(LHND, iFilterH * iFilterW); 
	 
	// 判断是否内存分配失败 
	if (hArray == NULL) 
	{ 
		// 释放内存 
		LocalUnlock(hNewDIBBits); 
		LocalFree(hNewDIBBits); 
		 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	aValue = (unsigned char * )LocalLock(hArray); 
	 
	// 开始中值滤波 
	switch(nBitCount) 
	{ 
	case 8: 
		// 行(除去边缘几行) 
		for(i = iFilterMY; i < lHeight - iFilterH + iFilterMY + 1; i++) 
		{ 
			// 列(除去边缘几列) 
			for(j = iFilterMX; j < lWidth - iFilterW + iFilterMX + 1; j++) 
			{ 
				// 指向新DIB第i行,第j个象素的指针 
				lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j; 
				 
				// 读取滤波器数组 
				for (k = 0; k < iFilterH; k++) 
				{ 
					for (l = 0; l < iFilterW; l++) 
					{ 
						// 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针 
						lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iFilterMY - k) + j - iFilterMX + l; 
						 
						// 保存象素值 
						aValue[k * iFilterW + l] = *lpSrc; 
					} 
				} 
				 
				// 获取中值 
				* lpDst = GetMedianNum(aValue, iFilterH * iFilterW); 
			} 
		} 
		break; 
	case 24: 
		// 行(除去边缘几行) 
		for(i = iFilterMY; i < lHeight - iFilterH + iFilterMY + 1; i++) 
		{ 
			// 列(除去边缘几列) 
			for(j = iFilterMX; j < lWidth - iFilterW + iFilterMX + 1; j++) 
			{ 
				for(rgb = 0; rgb < 3; rgb++) 
				{ 
					// 指向新DIB第i行,第j个象素的指针 
					lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + rgb; 
					 
					// 读取滤波器数组 
					for (k = 0; k < iFilterH; k++) 
					{ 
						for (l = 0; l < iFilterW; l++) 
						{ 
							// 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针 
							lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iFilterMY - k) + (j - iFilterMX + l) * 3 + rgb; 
							 
							// 保存象素值 
							aValue[k * iFilterW + l] = *lpSrc; 
						} 
					} 
					 
					// 获取中值 
					* lpDst = GetMedianNum(aValue, iFilterH * iFilterW); 
				} 
			} 
		} 
	} 
	// 复制变换后的图像 
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); 
	 
	// 释放内存 
	LocalUnlock(hNewDIBBits); 
	LocalFree(hNewDIBBits); 
	LocalUnlock(hArray); 
	LocalFree(hArray); 
	 
	// 返回 
	return TRUE; 
} 
/************************************************************************* 
 * 
 * 函数名称: 
 *   GetMedianNum() 
 * 
 * 参数: 
 *   unsigned char * bpArray	- 指向要获取中值的数组指针 
 *   int   iFilterLen			- 数组长度 
 * 
 * 返回值: 
 *   unsigned char      - 返回指定数组的中值。 
 * 
 * 说明: 
 *   该函数用冒泡法对一维数组进行排序,并返回数组元素的中值。 
 * 
 ************************************************************************/ 
 
unsigned char WINAPI GetMedianNum(unsigned char * bArray, int iFilterLen) 
{ 
	// 循环变量 
	int		i; 
	int		j; 
	 
	// 中间变量 
	unsigned char bTemp; 
	 
	// 用冒泡法对数组进行排序 
	for (j = 0; j < iFilterLen - 1; j ++) 
	{ 
		for (i = 0; i < iFilterLen - j - 1; i ++) 
		{ 
			if (bArray[i] > bArray[i + 1]) 
			{ 
				// 互换 
				bTemp = bArray[i]; 
				bArray[i] = bArray[i + 1]; 
				bArray[i + 1] = bTemp; 
			} 
		} 
	} 
	 
	// 计算中值 
	if ((iFilterLen & 1) > 0) 
	{ 
		// 数组有奇数个元素,返回中间一个元素 
		bTemp = bArray[(iFilterLen + 1) / 2]; 
	} 
	else 
	{ 
		// 数组有偶数个元素,返回中间两个元素平均值 
		bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2; 
	} 
	 
	// 返回中值 
	return bTemp; 
} 
/************************************************************************* 
 * 
 * 函数名称: 
 *  GaussDIB() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits    - 指向源DIB图像指针 
 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数) 
 *   LONG  lHeight      - 源图像高度(象素数) 
 * 返回值: 
 *   BOOL               - 边缘检测成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 * 该函数用高斯拉普拉斯边缘检测算子对图像进行边缘检测运算。 
 *  
 * 要求目标图像为灰度图像。 
 ************************************************************************/ 
 
BOOL WINAPI GaussDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int nBitCount) 
{ 
	 
	// 指向缓存图像的指针 
	LPSTR	lpDst1; 
	LPSTR	lpDst2; 
	 
	// 指向缓存DIB图像的指针 
	LPSTR	lpNewDIBBits1; 
	HLOCAL	hNewDIBBits1; 
	LPSTR	lpNewDIBBits2; 
	HLOCAL	hNewDIBBits2; 
 
	// 模板高度 
	int		iTempH; 
	 
	// 模板宽度 
	int		iTempW; 
	 
	// 模板系数 
	FLOAT	fTempC; 
	 
	// 模板中心元素X坐标 
	int		iTempMX; 
	 
	// 模板中心元素Y坐标 
	int		iTempMY; 
	 
	//模板数组 
	FLOAT aTemplate[25]; 
 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); 
 
	if (hNewDIBBits1 == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1); 
 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); 
 
	if (hNewDIBBits2 == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2); 
 
	// 拷贝源图像到缓存图像中 
	lpDst1 = (char *)lpNewDIBBits1; 
	memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
	lpDst2 = (char *)lpNewDIBBits2; 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
 
 
	// 设置Gauss模板参数 
	iTempW = 5; 
	iTempH = 5; 
	fTempC = 1.0; 
	iTempMX = 3; 
	iTempMY = 3; 
	aTemplate[0] = -2.0; 
	aTemplate[1] = -4.0; 
	aTemplate[2] = -4.0; 
	aTemplate[3] = -4.0; 
	aTemplate[4] = -2.0; 
	aTemplate[5] = -4.0; 
	aTemplate[6] = 0.0; 
	aTemplate[7] = 8.0; 
	aTemplate[8] = 0.0; 
	aTemplate[9] = -4.0; 
	aTemplate[10] = -4.0; 
	aTemplate[11] = 8.0; 
	aTemplate[12] = 24.0; 
	aTemplate[13] = 8.0; 
	aTemplate[14] = -4.0; 
	aTemplate[15] = -4.0; 
	aTemplate[16] = 0.0; 
	aTemplate[17] = 8.0; 
	aTemplate[18] = 0.0; 
	aTemplate[19] = -4.0; 
	aTemplate[20] = -2.0; 
	aTemplate[21] = -4.0; 
	aTemplate[22] = -4.0; 
	aTemplate[23] = -4.0; 
	aTemplate[24] = -2.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits1, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	// 复制经过模板运算后的图像到源图像 
	memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight * (nBitCount / 8)); 
 
	// 释放内存 
	LocalUnlock(hNewDIBBits1); 
	LocalFree(hNewDIBBits1); 
 
	LocalUnlock(hNewDIBBits2); 
	LocalFree(hNewDIBBits2); 
	// 返回 
	return TRUE; 
} 
/************************************************************************* 
 * 
 * 函数名称: 
 *   KirschDIB() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits    - 指向源DIB图像指针 
 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数) 
 *   LONG  lHeight      - 源图像高度(象素数) 
 * 返回值: 
 *   BOOL               - 边缘检测成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 * 该函数用kirsch边缘检测算子对图像进行边缘检测运算。 
 *  
 * 要求目标图像为灰度图像。 
 ************************************************************************/ 
 
BOOL WINAPI KirschDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int nBitCount) 
{ 
	 
	// 指向缓存图像的指针 
	LPSTR	lpDst1; 
	LPSTR	lpDst2; 
	 
	// 指向缓存DIB图像的指针 
	LPSTR	lpNewDIBBits1; 
	HLOCAL	hNewDIBBits1; 
	LPSTR	lpNewDIBBits2; 
	HLOCAL	hNewDIBBits2; 
 
	//循环变量 
	long i; 
	long j; 
	int  k; 
	// 模板高度 
	int		iTempH; 
	 
	// 模板宽度 
	int		iTempW; 
	 
	// 模板系数 
	FLOAT	fTempC; 
	 
	// 模板中心元素X坐标 
	int		iTempMX; 
	 
	// 模板中心元素Y坐标 
	int		iTempMY; 
	 
	//模板数组 
	FLOAT aTemplate[9]; 
 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); 
 
	if (hNewDIBBits1 == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1); 
 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); 
 
	if (hNewDIBBits2 == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2); 
 
	// 拷贝源图像到缓存图像中 
	lpDst1 = (char *)lpNewDIBBits1; 
	memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
	lpDst2 = (char *)lpNewDIBBits2; 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
 
 
	// 设置Kirsch模板1参数 
	iTempW = 3; 
	iTempH = 3; 
	fTempC = 1.0; 
	iTempMX = 1; 
	iTempMY = 1; 
	aTemplate[0] = 5.0; 
	aTemplate[1] = 5.0; 
	aTemplate[2] = 5.0; 
	aTemplate[3] = -3.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = -3.0; 
	aTemplate[6] = -3.0; 
	aTemplate[7] = -3.0; 
	aTemplate[8] = -3.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits1, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	// 设置Kirsch模板2参数 
	aTemplate[0] = -3.0; 
	aTemplate[1] = 5.0; 
	aTemplate[2] = 5.0; 
	aTemplate[3] = -3.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = 5.0; 
	aTemplate[6] = -3.0; 
	aTemplate[7] = -3.0; 
	aTemplate[8] = -3.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits2, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	//求两幅缓存图像的最大值 
	for(j = 0; j  *lpDst1) 
					*lpDst1 = *lpDst2; 
			} 
		} 
	} 
 
	// 拷贝源图像到缓存图像中 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
 
	// 设置Kirsch模板3参数 
	aTemplate[0] = -3.0; 
	aTemplate[1] = -3.0; 
	aTemplate[2] = 5.0; 
	aTemplate[3] = -3.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = 5.0; 
	aTemplate[6] = -3.0; 
	aTemplate[7] = -3.0; 
	aTemplate[8] = 5.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits2, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	//求两幅缓存图像的最大值 
	for(j = 0; j  *lpDst1) 
					*lpDst1 = *lpDst2; 
			} 
		} 
	} 
 
	// 拷贝源图像到缓存图像中 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
	 
	// 设置Kirsch模板4参数 
	aTemplate[0] = -3.0; 
	aTemplate[1] = -3.0; 
	aTemplate[2] = -3.0; 
	aTemplate[3] = -3.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = 5.0; 
	aTemplate[6] = -3.0; 
	aTemplate[7] = 5.0; 
	aTemplate[8] = 5.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits2, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	//求两幅缓存图像的最大值 
	for(j = 0; j  *lpDst1) 
					*lpDst1 = *lpDst2; 
			} 
		} 
	} 
 
	// 拷贝源图像到缓存图像中 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
	 
	// 设置Kirsch模板5参数 
	aTemplate[0] = -3.0; 
	aTemplate[1] = -3.0; 
	aTemplate[2] = -3.0; 
	aTemplate[3] = -3.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = -3.0; 
	aTemplate[6] = 5.0; 
	aTemplate[7] = 5.0; 
	aTemplate[8] = 5.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits2, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	// 拷贝源图像到缓存图像中 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
	//求两幅缓存图像的最大值 
	for(j = 0; j  *lpDst1) 
					*lpDst1 = *lpDst2; 
			} 
		} 
	} 
 
	// 拷贝源图像到缓存图像中 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
	 
	// 设置Kirsch模板6参数 
	aTemplate[0] = -3.0; 
	aTemplate[1] = -3.0; 
	aTemplate[2] = -3.0; 
	aTemplate[3] = 5.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = -3.0; 
	aTemplate[6] = 5.0; 
	aTemplate[7] = 5.0; 
	aTemplate[8] = -3.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits2, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	//求两幅缓存图像的最大值 
	for(j = 0; j  *lpDst1) 
					*lpDst1 = *lpDst2; 
			} 
		} 
	} 
 
	// 拷贝源图像到缓存图像中 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
	 
	// 设置Kirsch模板7参数 
	aTemplate[0] = 5.0; 
	aTemplate[1] = -3.0; 
	aTemplate[2] = -3.0; 
	aTemplate[3] = 5.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = -3.0; 
	aTemplate[6] = 5.0; 
	aTemplate[7] = -3.0; 
	aTemplate[8] = -3.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits2, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	//求两幅缓存图像的最大值 
	for(j = 0; j  *lpDst1) 
					*lpDst1 = *lpDst2; 
			} 
		} 
	} 
 
	// 拷贝源图像到缓存图像中 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
	 
	// 设置Kirsch模板8参数 
	aTemplate[0] = 5.0; 
	aTemplate[1] = 5.0; 
	aTemplate[2] = -3.0; 
	aTemplate[3] = 5.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = -3.0; 
	aTemplate[6] = -3.0; 
	aTemplate[7] = -3.0; 
	aTemplate[8] = -3.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits2, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	//求两幅缓存图像的最大值 
	for(j = 0; j  *lpDst1) 
					*lpDst1 = *lpDst2; 
			} 
		} 
	} 
 
	// 复制经过模板运算后的图像到源图像 
	memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight * (nBitCount / 8)); 
 
	// 释放内存 
	LocalUnlock(hNewDIBBits1); 
	LocalFree(hNewDIBBits1); 
 
	LocalUnlock(hNewDIBBits2); 
	LocalFree(hNewDIBBits2); 
	// 返回 
	return TRUE; 
} 
/************************************************************************* 
 * 
 * 函数名称: 
 *   PrewittDIB() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits    - 指向源DIB图像指针 
 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数) 
 *   LONG  lHeight      - 源图像高度(象素数) 
 * 返回值: 
 *   BOOL               - 边缘检测成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 * 该函数用Prewitt边缘检测算子对图像进行边缘检测运算。 
 *  
 * 要求目标图像为灰度图像。 
 ************************************************************************/ 
 
BOOL WINAPI PrewittDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int nBitCount) 
{ 
	 
	// 指向缓存图像的指针 
	LPSTR	lpDst1; 
	LPSTR	lpDst2; 
	 
	// 指向缓存DIB图像的指针 
	LPSTR	lpNewDIBBits1; 
	HLOCAL	hNewDIBBits1; 
	LPSTR	lpNewDIBBits2; 
	HLOCAL	hNewDIBBits2; 
 
	//循环变量 
	long i; 
	long j; 
	int  k; 
	// 模板高度 
	int		iTempH; 
	 
	// 模板宽度 
	int		iTempW; 
	 
	// 模板系数 
	FLOAT	fTempC; 
	 
	// 模板中心元素X坐标 
	int		iTempMX; 
	 
	// 模板中心元素Y坐标 
	int		iTempMY; 
	 
	//模板数组 
	FLOAT aTemplate[9]; 
 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); 
 
	if (hNewDIBBits1 == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1); 
 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); 
 
	if (hNewDIBBits2 == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2); 
 
	// 拷贝源图像到缓存图像中 
	lpDst1 = (char *)lpNewDIBBits1; 
	memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
	lpDst2 = (char *)lpNewDIBBits2; 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
 
 
	// 设置Prewitt模板参数 
	iTempW = 3; 
	iTempH = 3; 
	fTempC = 1.0; 
	iTempMX = 1; 
	iTempMY = 1; 
	aTemplate[0] = -1.0; 
	aTemplate[1] = -1.0; 
	aTemplate[2] = -1.0; 
	aTemplate[3] = 0.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = 0.0; 
	aTemplate[6] = 1.0; 
	aTemplate[7] = 1.0; 
	aTemplate[8] = 1.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits1, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	// 设置Prewitt模板参数 
	aTemplate[0] = 1.0; 
	aTemplate[1] = 0.0; 
	aTemplate[2] = -1.0; 
	aTemplate[3] = 1.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = -1.0; 
	aTemplate[6] = 1.0; 
	aTemplate[7] = 0.0; 
	aTemplate[8] = -1.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits2, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	//求两幅缓存图像的最大值 
	for(j = 0; j  *lpDst1) 
					*lpDst1 = *lpDst2; 
			} 
		} 
	} 
 
	// 复制经过模板运算后的图像到源图像 
	memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight * (nBitCount / 8)); 
 
	// 释放内存 
	LocalUnlock(hNewDIBBits1); 
	LocalFree(hNewDIBBits1); 
 
	LocalUnlock(hNewDIBBits2); 
	LocalFree(hNewDIBBits2); 
	// 返回 
	return TRUE; 
} 
/************************************************************************* 
 * 
 * 函数名称: 
 *   RobertDIB() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits    - 指向源DIB图像指针 
 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数) 
 *   LONG  lHeight      - 源图像高度(象素数) 
 * 返回值: 
 *   BOOL               - 边缘检测成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 * 该函数用Robert边缘检测算子对图像进行边缘检测运算。 
 *  
 * 要求目标图像为灰度图像。 
 ************************************************************************/ 
 
BOOL WINAPI RobertDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int nBitCount) 
{ 
	 
	// 指向源图像的指针 
	LPSTR	lpSrc; 
	 
	// 指向缓存图像的指针 
	LPSTR	lpDst; 
	 
	// 指向缓存DIB图像的指针 
	LPSTR	lpNewDIBBits; 
	HLOCAL	hNewDIBBits; 
 
	//循环变量 
	long i; 
	long j; 
	int	 k; 
 
	//像素值 
	double result; 
	unsigned char pixel[4]; 
 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); 
 
	if (hNewDIBBits == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits = (char * )LocalLock(hNewDIBBits); 
 
	// 初始化新分配的内存,设定初始值为255 
	lpDst = (char *)lpNewDIBBits; 
	memset(lpDst, (BYTE)255, lWidth * lHeight * (nBitCount / 8)); 
	 
	switch(nBitCount) 
	{ 
	case 8: 
		//使用水平方向的结构元素进行腐蚀 
		for(j = lHeight-1; j > 0; j--) 
		{ 
			for(i = 0;i  0; j--) 
		{ 
			for(i = 0; i < lWidth-1; i++) 
			{ 
				//由于使用2×2的模板,为防止越界,所以不处理最下边和最右边的两列像素 
				for(k = 0; k < 3; k++) 
				{ 
					// 指向源图像第j行,第i个象素的指针			 
					lpSrc = (char *)lpDIBBits + lWidth * j * 3 + i * 3 + k; 
					// 指向目标图像第j行,第i个象素的指针			 
					lpDst = (char *)lpNewDIBBits + lWidth * j * 3 + i * 3 + k; 
					 
					//取得当前指针处2*2区域的像素值,注意要转换为unsigned char型 
					pixel[0] = (unsigned char)*lpSrc; 
					pixel[1] = (unsigned char)*(lpSrc + 3); 
					pixel[2] = (unsigned char)*(lpSrc - lWidth * 3); 
					pixel[3] = (unsigned char)*(lpSrc - lWidth * 3 + 3); 
					 
					//计算目标图像中的当前点 
					result = sqrt(( pixel[0] - pixel[3] )*( pixel[0] - pixel[3] ) + \ 
						( pixel[1] - pixel[2] )*( pixel[1] - pixel[2] )); 
					*lpDst = (unsigned char)result; 
				} 
			} 
		} 
		break; 
	} 
 
	// 复制腐蚀后的图像 
	memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight * (nBitCount / 8)); 
 
	// 释放内存 
	LocalUnlock(hNewDIBBits); 
	LocalFree(hNewDIBBits); 
 
	// 返回 
	return TRUE; 
} 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   SobelDIB() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits    - 指向源DIB图像指针 
 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数) 
 *   LONG  lHeight      - 源图像高度(象素数) 
 * 返回值: 
 *   BOOL               - 边缘检测成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 * 该函数用Sobel边缘检测算子对图像进行边缘检测运算。 
 *  
 * 要求目标图像为灰度图像。 
 ************************************************************************/ 
 
BOOL WINAPI SobelDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int nBitCount) 
{ 
	 
	// 指向缓存图像的指针 
	LPSTR	lpDst1; 
	LPSTR	lpDst2; 
	 
	// 指向缓存DIB图像的指针 
	LPSTR	lpNewDIBBits1; 
	HLOCAL	hNewDIBBits1; 
	LPSTR	lpNewDIBBits2; 
	HLOCAL	hNewDIBBits2; 
 
	//循环变量 
	long i; 
	long j; 
	int  k; 
	// 模板高度 
	int		iTempH; 
	 
	// 模板宽度 
	int		iTempW; 
	 
	// 模板系数 
	FLOAT	fTempC; 
	 
	// 模板中心元素X坐标 
	int		iTempMX; 
	 
	// 模板中心元素Y坐标 
	int		iTempMY; 
	 
	//模板数组 
	FLOAT aTemplate[9]; 
 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); 
 
	if (hNewDIBBits1 == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1); 
 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight * (nBitCount / 8)); 
 
	if (hNewDIBBits2 == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2); 
 
	// 拷贝源图像到缓存图像中 
	lpDst1 = (char *)lpNewDIBBits1; 
	memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
	lpDst2 = (char *)lpNewDIBBits2; 
	memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight * (nBitCount / 8)); 
 
	// 设置Sobel模板参数 
	iTempW = 3; 
	iTempH = 3; 
	fTempC = 1.0; 
	iTempMX = 1; 
	iTempMY = 1; 
	aTemplate[0] = -1.0; 
	aTemplate[1] = -2.0; 
	aTemplate[2] = -1.0; 
	aTemplate[3] = 0.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = 0.0; 
	aTemplate[6] = 1.0; 
	aTemplate[7] = 2.0; 
	aTemplate[8] = 1.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits1, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	// 设置Sobel模板参数 
	aTemplate[0] = -1.0; 
	aTemplate[1] = 0.0; 
	aTemplate[2] = 1.0; 
	aTemplate[3] = -2.0; 
	aTemplate[4] = 0.0; 
	aTemplate[5] = 2.0; 
	aTemplate[6] = -1.0; 
	aTemplate[7] = 0.0; 
	aTemplate[8] = 1.0; 
 
	// 调用Template()函数 
	if (!Template(lpNewDIBBits2, lWidth, lHeight,  
		iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC, nBitCount)) 
	{ 
		return FALSE; 
	} 
 
	//求两幅缓存图像的最大值 
	for(j = 0; j  *lpDst1) 
					*lpDst1 = *lpDst2; 
			} 
		} 
	} 
 
	// 复制经过模板运算后的图像到源图像 
	memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight * (nBitCount / 8)); 
 
	// 释放内存 
	LocalUnlock(hNewDIBBits1); 
	LocalFree(hNewDIBBits1); 
 
	LocalUnlock(hNewDIBBits2); 
	LocalFree(hNewDIBBits2); 
	// 返回 
	return TRUE; 
} 
 
/************************************************************************* 
 * 
 * 函数名称: 
 *   To256DIB() 
 * 
 * 参数: 
 *   LPSTR lpDIBBits    - 指向源DIB图像指针 
 *   LONG  lWidth       - 源图像宽度(象素数,必须是4的倍数) 
 *   LONG  lHeight      - 源图像高度(象素数) 
 * 返回值: 
 *   BOOL               - 操作成功返回TRUE,否则返回FALSE。 
 * 
 * 说明: 
 * 该函数将真彩色转换为256等级灰度黑白图像。 
 *  
 * 要求目标图像为24位位图图像。 
 ************************************************************************/ 
 
BOOL WINAPI To256DIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight) 
{ 
	// 指向复制图像的指针 
	LPSTR	lpNewDIBBits; 
	HLOCAL	hNewDIBBits; 
	 
	// 指向源图像的指针 
	unsigned char*	lpSrcR; 
	unsigned char*	lpSrcG; 
	unsigned char*	lpSrcB; 
	// 指向要复制区域的指针 
	unsigned char*	lpDstR; 
	unsigned char*	lpDstG; 
	unsigned char*	lpDstB; 
	 
	// 循环变量 
	LONG	i; 
	LONG	j; 
	// 中间变量 
	int		bTemp; 
	// 图像每行的字节数 
	LONG lLineBytes; 
	lLineBytes = WIDTHBYTES(lWidth * 24); 
	 
	// 暂时分配内存,以保存新图像 
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); 
	 
	// 判断是否内存分配失败 
	if (hNewDIBBits == NULL) 
	{ 
		// 分配内存失败 
		return FALSE; 
	} 
	 
	// 锁定内存 
	lpNewDIBBits = (char * )LocalLock(hNewDIBBits); 
	 
	// 初始化图像为原始图像 
	memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight); 
 
	// 行(除去边缘几行) 
	for(i = 0; i < lHeight; i++) 
	{ 
		// 列(除去边缘几列) 
		for(j = 0; j < lWidth; j++) 
		{ 
			// 指向新DIB第i行,第j个象素的指针 
			lpDstR = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3; 
			lpDstG = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + 1; 
			lpDstB = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + 2; 
			lpSrcR = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3; 
			lpSrcG = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + 1; 
			lpSrcB = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j * 3 + 2; 
			bTemp = (int)(0.299 * (float)(* lpSrcR) + 0.587 * (float)(* lpSrcG) + 0.114 * (float)(* lpSrcB));	 
			if(bTemp > 255) 
				bTemp = 255; 
			else 
			{ 
				* lpDstR = bTemp; 
				* lpDstG = bTemp; 
				* lpDstB = bTemp; 
			} 
		} 
	} 
 
	// 复制变换后的图像 
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); 
	 
	// 释放内存 
	LocalUnlock(hNewDIBBits); 
	LocalFree(hNewDIBBits); 
	 
	// 返回 
	return TRUE; 
}