dibapi.cpp

来自「一个非常全的vc编程的原程序代码是关于图像处理的!」· C++ 代码 · 共 2,454 行 · 第 1/5 页

CPP
2,454 行
字号
///////////////////////////////////////////////////////////////
//以下开始是一些图像变换的函数

/**************************************************************
Rotate DIB 90 degree counter clockwise, and return the rotated
DIB in a new DIB handle, let the source DIB unchanged.
parameter:    HDIB
return:       HDIB
**************************************************************/
HDIB RotateDIB(HDIB hDib){
	SetCursor(LoadCursor(NULL, IDC_WAIT));

    //得到原始图像和目标图像的一些基本属性
	LPBYTE	lpDIBSrc		= (LPBYTE)GlobalLock(hDib);
	DWORD	lSrcHeight		= DIBHeight(lpDIBSrc);
	DWORD	lSrcWidth		= DIBWidth(lpDIBSrc);
    WORD	wBitCount		= ((LPBITMAPINFOHEADER)lpDIBSrc)->biBitCount;
	LPBYTE	lpOldBits		= FindDIBBits(lpDIBSrc);
	double	fColorBytes		= (double)((double)wBitCount/8.0);
	DWORD	lSrcRowBytes	= WIDTHBYTES(lSrcWidth*((DWORD)wBitCount));
	DWORD	lDestRowBytes	= WIDTHBYTES(lSrcHeight*((DWORD)wBitCount));
	DWORD dwDataLength = GlobalSize(hDib);
	dwDataLength += lDestRowBytes*(lSrcWidth-1)+
		            (DWORD)((lSrcHeight-1)*fColorBytes)-
				    lSrcRowBytes*(lSrcHeight-1)+
				    (DWORD)((lSrcWidth-1)*fColorBytes);
	
	//为目标图像分配内存并得到其指针
	HDIB hNewDib = GlobalAlloc(GHND,dwDataLength);
	if(!hNewDib){
    	SetCursor(LoadCursor(NULL,IDC_ARROW));
		return NULL;
	}
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);

	//填写目标图像的BITMAPINFOHEADER并拷贝调色板
	memcpy(lpDIB, lpDIBSrc, sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIBSrc));
	((LPBITMAPINFOHEADER)lpDIB)->biHeight = lSrcWidth;
	((LPBITMAPINFOHEADER)lpDIB)->biWidth  = lSrcHeight;

	//图像变换开始//////////////////////////////////////////
	LPBYTE lpData = FindDIBBits(lpDIB);

	DWORD i, j;
	switch(wBitCount){
	case 1:
		for(i=0;i<lSrcHeight;i++){
			for(j=0;j<lSrcWidth;j++){
				*(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/8))&=
					~(1<<(7-((lSrcHeight-i-1)%8)));
				*(lpData+(lDestRowBytes*j+(lSrcHeight-1)/8))|=
					((*(lpOldBits+(lSrcRowBytes*i+j/8))<<(j%8))>>7)<<
					(7-((lSrcHeight-i-1)%8));
			}
		}
		break;
	case 4:
		for(i=0;i<lSrcHeight;i++){
        	for(j=0;j<lSrcWidth;j++){
                *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/2))&=
					((lSrcHeight-i-1)%2)?0xf0:0x0f;
				*(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/2))|=
					((*(lpOldBits+(lSrcRowBytes*i+j/2))<<
					(j%2?4:0))>>4)<<(((lSrcHeight-i-1)%2)?0:4);
			}
		}
		break;
	case 8:
		for(i=0;i<lSrcHeight;++i){
        	for(j=0;j<lSrcWidth;++j){
                *(lpData+(lDestRowBytes*j+lSrcHeight-i-1))
					=*(lpOldBits+(lSrcRowBytes*i+j));
			}
		}
		break;
	case 24:
		for(i=0;i<lSrcHeight;i++){
        	for(j=0;j<lSrcWidth;j++){
                *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)*3))
					=*(lpOldBits+(lSrcRowBytes*i+j*3));
                *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)*3)+1)
					=*(lpOldBits+(lSrcRowBytes*i+j*3)+1);
                *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)*3)+2)
					=*(lpOldBits+(lSrcRowBytes*i+j*3)+2);
			}
		}
		break;
	}

	GlobalUnlock(hDib);
	GlobalUnlock(hNewDib);
    SetCursor(LoadCursor(NULL, IDC_ARROW));

	return hNewDib;
}
/****************************************************
Flip DIB horzonly and return the flipped DIB
in a new DIB handle, let the source DIB unchanged.
parameter:  HDIB
return:     HDIB
****************************************************/
HDIB FlipHorzDIB(HDIB hDib){
	SetCursor(LoadCursor(NULL, IDC_WAIT));
    
	DWORD	dwDataLength = GlobalSize(hDib);
	HDIB	hNewDib = GlobalAlloc(GHND, dwDataLength);
	if(!hNewDib){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	if(lpDIB == NULL){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
	
	LPBYTE lpDIBSrc = (LPBYTE)GlobalLock(hDib);
	
	memcpy(lpDIB, lpDIBSrc,
		   sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIBSrc));
    
	DWORD	lSrcWidth		= DIBWidth(lpDIBSrc);
	DWORD	lSrcHeight		= DIBHeight(lpDIBSrc);
	WORD	wBitCount		= ((LPBITMAPINFOHEADER)lpDIBSrc)->biBitCount;
	DWORD	lSrcRowBytes	= WIDTHBYTES(lSrcWidth*((DWORD)wBitCount));
	LPBYTE	lpOldBits		= FindDIBBits(lpDIBSrc);
	LPBYTE	lpData			= FindDIBBits(lpDIB);

	//图像变换开始//////////////////////////////////////////
	DWORD i, j;
	switch(wBitCount){
	case 1:
		for(i=0;i<lSrcHeight;i++){
			for(j=0;j<lSrcWidth;j++){
				*(lpData+(lSrcRowBytes*i+(lSrcWidth-j-1)/8))&=
					~(1<<(7-((lSrcWidth-j-1)%8)));
				*(lpData+(lSrcRowBytes*i+(lSrcWidth-j-1)/8))|=
					((*(lpOldBits+(lSrcRowBytes*i+j/8))<<(j%8))>>7)<<
					(7-(lSrcWidth-j-1)%8);
			}
		}
		break;
	case 4:
		for(i=0;i<lSrcHeight;i++){
			for(j=0;j<lSrcWidth;j++){
				*(lpData+(lSrcRowBytes*i+(lSrcWidth-j-1)/2))&=
					((lSrcWidth-j-1)%2)?0xf0:0x0f;
				*(lpData+(lSrcRowBytes*i+(lSrcWidth-j-1)/2))|=
					((*(lpOldBits+(lSrcRowBytes*i+j/2))<<
					(j%2?4:0))>>4)<<(((lSrcWidth-j-1)%2)?0:4);
			}
		}
		break;
	case 8:
		for(i=0;i<lSrcHeight;i++){
			for(j=0;j<lSrcWidth;j++){
				*(lpData+(lSrcRowBytes*i+lSrcWidth-j-1))
					=*(lpOldBits+(lSrcRowBytes*i+j));
			}
		}
		break;
	case 24:
		for(i=0;i<lSrcHeight;i++){
			for(j=0;j<lSrcWidth;j++){
				*(lpData+(lSrcRowBytes*i+(lSrcWidth-j-1)*3))
					=*(lpOldBits+(lSrcRowBytes*i+j*3));
				*(lpData+(lSrcRowBytes*i+(lSrcWidth-j-1)*3)+1)
					=*(lpOldBits+(lSrcRowBytes*i+j*3)+1);
				*(lpData+(lSrcRowBytes*i+(lSrcWidth-j-1)*3)+2)
					=*(lpOldBits+(lSrcRowBytes*i+j*3)+2);
			}
		}
		break;
	}

	GlobalUnlock(hDib);
	GlobalUnlock(hNewDib);
	SetCursor(LoadCursor(NULL, IDC_ARROW));
	
	return hNewDib;
}
/********************************************
Get difference of a DIB with itself. 
parameter:  HDIB
return:     HDIB
*********************************************/
HDIB SelfDiffDIB(HDIB hDib){
	SetCursor(LoadCursor(NULL, IDC_WAIT));
    
	DWORD	dwDataLength = GlobalSize(hDib);
	HDIB	hNewDib = GlobalAlloc(GHND,dwDataLength);
	if(!hNewDib){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	if(lpDIB == NULL){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
    
	LPBYTE lpDIBSrc = (LPBYTE)GlobalLock(hDib);
    
	memcpy(lpDIB, lpDIBSrc,
		   sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIBSrc));
    
    DWORD	lSrcWidth		= DIBWidth(lpDIBSrc);
	DWORD	lSrcHeight		= DIBHeight(lpDIBSrc);
	WORD	wBitCount		= ((LPBITMAPINFOHEADER)lpDIBSrc)->biBitCount;
	DWORD	lSrcRowBytes	= WIDTHBYTES(lSrcWidth*((DWORD)wBitCount));
	LPBYTE	lpOldBits		= FindDIBBits(lpDIBSrc);
	LPBYTE	lpData			= FindDIBBits(lpDIB);

	//图像变换开始//////////////////////////////////////////
	DWORD i, j;
	if(wBitCount == 8){
		for(i=0;i<lSrcHeight;i++){
			for(j=0;j<lSrcWidth-1;j++){
			    *(lpData+(lSrcRowBytes*i+j)) = (int)(*(lpOldBits+(lSrcRowBytes*i+j))
												 - *(lpOldBits+(lSrcRowBytes*i+j)+1))+127;
			}
		}
	}
    if(wBitCount == 24){
		for(i=0;i<lSrcHeight;i++){
			for(j=0;j<lSrcWidth-1;j++){
			    *(lpData+(lSrcRowBytes*i+j*3)) = (int)(*(lpOldBits+(lSrcRowBytes*i+j*3))
													 - *(lpOldBits+(lSrcRowBytes*i+j*3)+1))+127;
			    *(lpData+(lSrcRowBytes*i+j*3+1)) = (int)(*(lpOldBits+(lSrcRowBytes*i+j*3+1))
													 - *(lpOldBits+(lSrcRowBytes*i+j*3+1)+1))+127;
			    *(lpData+(lSrcRowBytes*i+j*3+2)) = (int)(*(lpOldBits+(lSrcRowBytes*i+j*3+2))
													 - *(lpOldBits+(lSrcRowBytes*i+j*3+2)+1))+127;
			}
		}
	}

	GlobalUnlock(hDib);
	GlobalUnlock(hNewDib);
	SetCursor(LoadCursor(NULL,IDC_ARROW));
	
	return hNewDib;
}
/********************************************
Revert all color of a DIB. 
parameter:  HDIB
return:     HDIB
*********************************************/
HDIB RevertColorDIB(HDIB hDib){
	SetCursor(LoadCursor(NULL, IDC_WAIT));
    
	DWORD dwDataLength = GlobalSize(hDib);
	HDIB  hNewDib = GlobalAlloc(GHND, dwDataLength);
	if(!hNewDib){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	if(lpDIB == NULL){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
    
	LPBYTE lpDIBSrc = (LPBYTE)GlobalLock(hDib);
    
	memcpy(lpDIB, lpDIBSrc,
		   sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIBSrc));
    
    DWORD	lSrcWidth		= DIBWidth(lpDIBSrc);
	DWORD	lSrcHeight		= DIBHeight(lpDIBSrc);
	WORD	wBitCount		= ((LPBITMAPINFOHEADER)lpDIBSrc)->biBitCount;
	DWORD	lSrcRowBytes	= WIDTHBYTES(lSrcWidth*((DWORD)wBitCount));
	LPBYTE	lpOldBits		= FindDIBBits(lpDIBSrc);
	LPBYTE	lpData			= FindDIBBits(lpDIB);

	//图像变换开始//////////////////////////////////////////
	DWORD i,j;
	if(wBitCount == 8){
		for(i=0;i<lSrcHeight;i++){
			for(j=0;j<lSrcWidth;j++){
				*(lpData+(lSrcRowBytes*i+j))
					= 255-*(lpOldBits+(lSrcRowBytes*i+j));
			}
		}
	}
    if(wBitCount == 24){
		for(i=0;i<lSrcHeight;i++){
			for(j=0;j<lSrcWidth-1;j++){
			   *(lpData+(lSrcRowBytes*i+j*3))
					= 255-*(lpOldBits+(lSrcRowBytes*i+j*3));
			   *(lpData+(lSrcRowBytes*i+j*3)+1)
					= 255-*(lpOldBits+(lSrcRowBytes*i+j*3)+1);
			   *(lpData+(lSrcRowBytes*i+j*3)+2)
					= 255-*(lpOldBits+(lSrcRowBytes*i+j*3)+2);
			}
		}
	}

	GlobalUnlock(hDib);
	GlobalUnlock(hNewDib);
	SetCursor(LoadCursor(NULL,IDC_ARROW));
	
	return hNewDib;
}
/********************************************
Convert color DIB to gray DIB.
parameter:  HDIB
return:     HDIB
*********************************************/
HDIB ColorDIBToGrayDIB(HDIB hDib){
	SetCursor(LoadCursor(NULL, IDC_WAIT));
    
	DWORD   dwDataLength = GlobalSize(hDib);
	HDIB	hNewDib = GlobalAlloc(GHND, dwDataLength);
	if(!hNewDib){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	if(lpDIB == NULL){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
    
	LPBYTE lpDIBSrc = (LPBYTE)GlobalLock(hDib);
    
    DWORD lSrcWidth   = DIBWidth(lpDIBSrc);
	DWORD lSrcHeight  = DIBHeight(lpDIBSrc);
	WORD  wBitCount	  = ((LPBITMAPINFOHEADER)lpDIBSrc)->biBitCount;
    DWORD lDestWidth  = lSrcWidth;
	DWORD lDestHeight = lSrcHeight;

	memcpy(lpDIB, lpDIBSrc,
		   sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIBSrc));
    
	DWORD  lSrcRowBytes  = WIDTHBYTES(lSrcWidth*((DWORD)wBitCount));
    DWORD  lDestRowBytes = lSrcRowBytes;
	LPBYTE lpOldBits	 = FindDIBBits(lpDIBSrc);
	LPBYTE lpData		 = FindDIBBits(lpDIB);

	//图像变换开始//////////////////////////////////////////
	DWORD i, j;
	if(wBitCount == 24){
		for(i=0;i<lSrcHeight;i++){
			for(j=0;j<lSrcWidth;j++){
			   *(lpData+lDestRowBytes*i+j*3)=
			   *(lpData+(lSrcRowBytes*i+j*3)+1)=
			   *(lpData+(lSrcRowBytes*i+j*3)+2)=
			        (BYTE)(0.11*(float)(*(lpOldBits+(lSrcRowBytes*i+j*3)))
					    +0.59*(float)(*(lpOldBits+(lSrcRowBytes*i+j*3)+1)) 
					    +0.30*(float)(*(lpOldBits+(lSrcRowBytes*i+j*3)+2)));
			}
		}
	}

	GlobalUnlock(hDib);
	GlobalUnlock(hNewDib);
	SetCursor(LoadCursor(NULL, IDC_ARROW));
	
	return hNewDib;
}

/*************************************************
Choice the best threshold by mathematics approach,
dispatch the DIB with the threshold choiced.
parameter:  HDIB
return:     HDIB
*************************************************/
HDIB AutoBinaryDIB(HDIB hDib){
	SetCursor(LoadCursor(NULL, IDC_WAIT));
    
	DWORD dwDataLength = GlobalSize(hDib);
	HDIB  hNewDib = GlobalAlloc(GHND, dwDataLength);
	if(!hNewDib){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	if(lpDIB == NULL){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
    
	LPBYTE lpDIBSrc = (LPBYTE)GlobalLock(hDib);
    
	memcpy(lpDIB, lpDIBSrc,
		   sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIBSrc));
    
    DWORD	lSrcWidth		= DIBWidth(lpDIBSrc);
	DWORD	lSrcHeight		= DIBHeight(lpDIBSrc);
	WORD	wBitCount		= ((LPBITMAPINFOHEADER)lpDIBSrc)->biBitCount;
	DWORD	lSrcRowBytes	= WIDTHBYTES(lSrcWidth*((DWORD)wBitCount));
	LPBYTE	lpOldBits		= FindDIBBits(lpDIBSrc);
	LPBYTE	lpData			= FindDIBBits(lpDIB);

	//图像变换开始//////////////////////////////////////////
	DWORD i, j;
	long  IOD;
	int   threshold;
	if(wBitCount == 8){
		//计算阈值
		IOD = 0;
		for(i=0;i<lSrcHeight;i++)
			for(j=0;j<lSrcWidth;j++)
				IOD += *(lpOldBits+lSrcRowBytes*i+j);
		threshold = (int)(IOD/lSrcWidth/lSrcHeight);

		//二值化
		for(i=0;i<lSrcHeight;i++)
			for(j=0;j<lSrcWidth;j++)
				if(*(lpOldBits+lSrcRowBytes*i+j) > threshold)
					*(lpData+lSrcRowBytes*i+j) = 255;
				else  *(lpData+lSrcRowBytes*i+j) = 0;

	}

	if(wBitCount == 24){
		//计算阈值
		IOD = 0;
		for(i=0;i<lSrcHeight;i++)
			for(j=0;j<lSrcWidth;j++)
				IOD += (long)(0.11*(*(lpOldBits+(lSrcRowBytes*i+j*3)))
				        +0.59*(*(lpOldBits+(lSrcRowBytes*i+j*3)+1)) 
					    +0.30*(*(lpOldBits+(lSrcRowBytes*i+j*3)+2)));
		threshold = (int)(IOD/lSrcWidth/lSrcHeight);

		//二值化
		for(i=0;i<lSrcHeight;i++)
			for(j=0;j<lSrcWidth;j++)
				if((long)(0.11*(*(lpOldBits+(lSrcRowBytes*i+j*3)))
				        +0.59*(*(lpOldBits+(lSrcRowBytes*i+j*3)+1)) 
					    +0.30*(*(lpOldBits+(lSrcRowBytes*i+j*3)+2)))
					> threshold)
					*(lpData+(lSrcRowBytes*i+j*3)) =
			        *(lpData+(lSrcRowBytes*i+j*3)+1) =
			        *(lpData+(lSrcRowBytes*i+j*3)+2) = 255;
				else
					*(lpData+(lSrcRowBytes*i+j*3)) =
			        *(lpData+(lSrcRowBytes*i+j*3)+1) =
			        *(lpData+(lSrcRowBytes*i+j*3)+2) = 0;
		
	}

	GlobalUnlock(hDib);
	GlobalUnlock(hNewDib);
	SetCursor(LoadCursor(NULL, IDC_ARROW));
	
	return hNewDib;
}
/*************************************************
Histogram equivalization.
parameter:  HDIB
return:     HDIB
*************************************************/
HDIB HistoEquivalizeDIB(HDIB hDib){
	SetCursor(LoadCursor(NULL, IDC_WAIT));
    
	DWORD dwDataLength = GlobalSize(hDib);
	HDIB  hNewDib = GlobalAlloc(GHND, dwDataLength);
	if(!hNewDib){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	if(lpDIB == NULL){
    	SetCursor(LoadCursor(NULL, IDC_ARROW));
		return NULL;
	}
    
	LPBYTE lpDIBSrc = (LPBYTE)GlobalLock(hDib);
    
	memcpy(lpDIB, lpDIBSrc,
		   sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIBSrc));
    
    DWORD	lSrcWidth		= DIBWidth(lpDIBSrc);
	DWORD	lSrcHeight		= DIBHeight(lpDIBSrc);
	WORD	wBitCount		= ((LPBITMAPINFOHEADER)lpDIBSrc)->biBitCount;
	DWORD	lSrcRowBytes	= WIDTHBYTES(lSrcWidth*((DWORD)wBitCount));
	LPBYTE	lpOldBits		= FindDIBBits(lpDIBSrc);
	LPBYTE	lpData			= FindDIBBits(lpDIB);

	//图像变换开始//////////////////////////////////////////
	DWORD i, j;
	if(wBitCount == 8){
		//统计各亮度的象素点个数
		double v[256];
		for(i=0;i<256;i++) v[i]=0.0;
		for(i=0;i<lSrcHeight;i++)
			for(j=0;j<lSrcWidth;j++)
				v[*(lpOldBits+lSrcRowBytes*i+j)] += 1.0;
  

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?