dibapi.cpp

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

CPP
2,454
字号
#include "DibAPI.h"
#include "StdAfx.h"
#include "math.h"
#include "DComplex.h"

#include "MACRO.h"

/*************************************************************
function inplementation goes here.
*************************************************************/

/********************************************************/
/*********  some property functions go here.   **********/
/********************************************************/

///////////////////////////////////////////////////////////
//得到x轴方向的象素分辨率
long XPelsPerMeter(LPBYTE lpDib)
{
	return ((LPBITMAPINFOHEADER)lpDib)->biXPelsPerMeter;
}
long XPelsPerMeter(HDIB hDib)
{
	LPBYTE lpbi;
	lpbi = (LPBYTE)GlobalLock(hDib);
	long bytes = XPelsPerMeter(lpbi);
	GlobalUnlock(hDib);
	return bytes;
}
/////////////////////////////////////////////////////////////
//得到y轴方向的象素分辨率
long YPelsPerMeter(LPBYTE lpDib)
{
	return ((LPBITMAPINFOHEADER)lpDib)->biYPelsPerMeter;
}
long YPelsPerMeter(HDIB hDib)
{
	LPBYTE lpbi;
	lpbi = (LPBYTE)GlobalLock(hDib);
	long bytes = YPelsPerMeter(lpbi);
	GlobalUnlock(hDib);
	return bytes;
}
/////////////////////////////////////////////////////////////
//得到图像一行所用的byte数
DWORD BytesPerLine(LPBYTE lpDib)
{
	return WIDTHBYTES(((LPBITMAPINFOHEADER)lpDib)->biWidth*
					((LPBITMAPINFOHEADER)lpDib)->biPlanes*
					((LPBITMAPINFOHEADER)lpDib)->biBitCount);
}
DWORD BytesPerLine(HDIB hDib)
{
	LPBYTE lpbi;
	lpbi = (LPBYTE)GlobalLock(hDib);
	DWORD bytes = BytesPerLine(lpbi);
	GlobalUnlock(hDib);
	return bytes;
}
/////////////////////////////////////////////////////////////
//得到图像中总共可以有的颜色数,0代表真彩色
WORD DIBNumColors(LPBYTE lpDib)
{
	WORD wBitCount;

	if(IS_WIN30_DIB(lpDib))
	{
		DWORD dwClrUsed;
		dwClrUsed = ((LPBITMAPINFOHEADER)lpDib)->biClrUsed;
		if(dwClrUsed)
			return (WORD)dwClrUsed;
	}
	
	if(IS_WIN30_DIB(lpDib))
		wBitCount = ((LPBITMAPINFOHEADER)lpDib)->biBitCount;
	else
		wBitCount = ((LPBITMAPCOREHEADER)lpDib)->bcBitCount;

	switch(wBitCount)
	{
	case 1:
		return 2;
	case 4:
		return 16;
	case 8:
		return 256;
	default:
		return 0;
	}
}
WORD DIBNumColors(HDIB hDib)
{
	LPBYTE lpbi;

	lpbi=(LPBYTE)GlobalLock(hDib);
	WORD color=DIBNumColors(lpbi);	
	GlobalUnlock(hDib);
	return color;
}
/////////////////////////////////////////////////////////////
//得到调色板大小
WORD PaletteSize(LPBYTE lpDib)
{
	return (WORD)(DIBNumColors(lpDib)*sizeof(RGBQUAD));
}
WORD PaletteSize(HDIB hDib)
{
	LPBYTE lpbi;
	lpbi=(LPBYTE)GlobalLock(hDib);
	WORD size=PaletteSize(lpbi);
	GlobalUnlock(hDib);
	return size;
}
/////////////////////////////////////////////////////////////
//得到DIB块总共的大小
DWORD DIBlockSize(LPBYTE lpDib)
{
	if(((LPBITMAPINFOHEADER)lpDib)->biSizeImage==0)
		((LPBITMAPINFOHEADER)lpDib)->biSizeImage = BytesPerLine(lpDib)*((LPBITMAPINFOHEADER)lpDib)->biHeight;

	return ((LPBITMAPINFOHEADER)lpDib)->biSize+PaletteSize(lpDib)+((LPBITMAPINFOHEADER)lpDib)->biSizeImage;
}
DWORD DIBlockSize(HDIB hDib)
{
	LPBYTE lpbi;
	lpbi = (LPBYTE)GlobalLock(hDib);
	DWORD bytes = DIBlockSize(lpbi);
	GlobalUnlock(hDib);
	return bytes;
}
/////////////////////////////////////////////////////////////
//得到图像高度
DWORD DIBHeight(LPBYTE lpDib)
{
	return ((LPBITMAPINFOHEADER)lpDib)->biHeight;
}
DWORD DIBHeight(HDIB hDib)
{
	LPBYTE lpbi;
	lpbi=(LPBYTE)GlobalLock(hDib);
	DWORD bytes=DIBHeight(lpbi);
	GlobalUnlock(hDib);
	return bytes;
}
/////////////////////////////////////////////////////////////
//得到图像的宽度
DWORD DIBWidth(LPBYTE lpDib)
{
	return ((LPBITMAPINFOHEADER)lpDib)->biWidth;
}
DWORD DIBWidth(HDIB hDib)
{
	LPBYTE lpbi;
	lpbi = (LPBYTE)GlobalLock(hDib);
	DWORD bytes = DIBWidth(lpbi);
	GlobalUnlock(hDib);
	return bytes;
}
/////////////////////////////////////////////////////////////
//得到表示一个象素所用的位数
WORD DIBBitCount(LPBYTE lpDib)
{
	return ((LPBITMAPINFOHEADER)lpDib)->biBitCount;
}

WORD DIBBitCount(HDIB hDib)
{
	LPBYTE lpbi;
	lpbi=(LPBYTE)GlobalLock(hDib);
	WORD bit=DIBBitCount(lpbi);
	GlobalUnlock(hDib);
	return bit;
}
/////////////////////////////////////////////////////////////
//得到指向图像信息的指针
LPBYTE FindDIBBits(LPBYTE lpDib)
{
	return lpDib+((LPBITMAPINFOHEADER)lpDib)->biSize+DIBNumColors(lpDib)*sizeof(RGBQUAD);
}

/********************************************************/
/*********  property functions end here.   **************/
/********************************************************/

/***************************************************
This function allocates memory for and initializes
a new DIB by filling in the BITMAPINFOHEADER,
allocating memory for the color table,and allocating 
memory for the bitmap bits.
parameter:		DWORD dwWidth	--图像宽
				DWORD dwHeight	--图像高
				WORD wBitCount	--表示一个象素所用的位数
return:			HDIB
***************************************************/
HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount)
{
	BITMAPINFOHEADER	bi;
	LPBITMAPINFOHEADER	lpbi;
	DWORD				dwLen;
	HDIB				hDib;
	DWORD				dwBytesPerLine;

	if(wBitCount <= 1)
		wBitCount = 1;
	else if(wBitCount <= 4)
		wBitCount = 4;
	else if(wBitCount <= 8)
		wBitCount = 8;
	else if(wBitCount <= 24)
		wBitCount =24;
	else 
		wBitCount = 4;
	
	bi.biSize			= sizeof(BITMAPINFOHEADER);
	bi.biHeight			= dwHeight;
	bi.biWidth			= dwWidth;
	bi.biPlanes			= 1;
	bi.biBitCount		= wBitCount;
	bi.biCompression	= BI_RGB;
	bi.biSizeImage		= 0;	
	bi.biXPelsPerMeter	= 0;
	bi.biYPelsPerMeter	= 0;
	bi.biClrUsed		= 0;
	bi.biClrImportant	= 0;

	dwBytesPerLine = WIDTHBYTES(wBitCount*dwWidth);
	dwLen = bi.biSize+PaletteSize((LPBYTE)&bi)+(dwBytesPerLine*dwHeight);
	
	hDib = GlobalAlloc(GHND,dwLen);
	if(!hDib)
		return NULL;
	
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
	
	*lpbi = bi;
	
	GlobalUnlock(hDib);
	
	return hDib;
}
/******************************************************
get number of entries of device's palette.
parameter:    HDC
return:       int(number of palette entries on device.)
******************************************************/
int PalEntriesOnDevice(HDC hDC)
{
	int nColors;
	nColors = (1<<(GetDeviceCaps(hDC,BITSPIXEL)*GetDeviceCaps(hDC,PLANES)));
	ASSERT(nColors);
	return nColors;
}/*****************************************************
create a DIB with default parameters.
parameter:      DWORD dwWidth	--图像宽
				DWORD dwHeight	--图像高
return:         HDIB
*****************************************************/
HDIB CreateDefaultDIB(DWORD dwWidth, DWORD dwHeight)
{
	HDC hDC = GetDC(NULL);
	if(!hDC)
		return NULL;

	int nDeviceDibPixel = GetDeviceCaps(hDC,BITSPIXEL);		
	
	HDIB hDib = CreateDIB(dwWidth,dwHeight,nDeviceDibPixel);
	
	LPBITMAPINFO lpbmi = (LPBITMAPINFO)GlobalLock(hDib);
	LPBYTE lpDibbits = FindDIBBits((LPBYTE)lpbmi);
	DWORD dwBitsSize = lpbmi->bmiHeader.biHeight*BytesPerLine((LPBYTE)&(lpbmi->bmiHeader));

	for(DWORD l=0;l<dwBitsSize;l++)
		lpDibbits[l] = 0xff;

	if(nDeviceDibPixel>8)
	{
		GlobalUnlock(hDib);
		ReleaseDC(NULL, hDC);
		return hDib;
	}

	int nColors = PalEntriesOnDevice(hDC);
	
	PALETTEENTRY pe[256];
	GetSystemPaletteEntries(hDC, 0, nColors, pe);

	for(int i=0;i<nColors;i++)
	{
		lpbmi->bmiColors[i].rgbRed		= pe[i].peRed;
		lpbmi->bmiColors[i].rgbGreen	= pe[i].peGreen;
		lpbmi->bmiColors[i].rgbBlue		= pe[i].peBlue;
		lpbmi->bmiColors[i].rgbReserved	= 0;
	}
	
	GlobalUnlock(hDib);
	ReleaseDC(NULL, hDC);

	return hDib;
}
/**************************************************
read in the specified DIB file into a global chunk
of memory.
parameter:     HANDLE(handle to the wanted file.)
return:        HANDLE(handle to a dib data buffer.)
**************************************************/
HDIB ReadDIBFile(HANDLE hFile)
{
	BITMAPFILEHEADER	bmfHeader;
	DWORD				dwBitsSize;
	UINT				nNumColors;	//颜色数
	HDIB				hDib;
	HANDLE				hDibtmp;
	LPBITMAPINFOHEADER	lpbi;
	DWORD				offBits;
	DWORD				dwRead;

	//得到文件大小
	dwBitsSize = GetFileSize(hFile, NULL);
	
	//为文件头和颜色表分配内存空间
	hDib = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)));
	if(!hDib)
		return NULL;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
	if(!lpbi)
	{
		GlobalFree(hDib);
		return NULL;
	}
	
	//读文件头的内容
	if(!ReadFile(hFile, (LPBYTE)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwRead, NULL))
		goto ErrExit;
	
	if(sizeof(BITMAPFILEHEADER) != dwRead)
		goto ErrExit;

	if(bmfHeader.bfType != 0x4d42)//如果不是'BM'格式的文件
		goto ErrExit;
	
	//读位图信息
	if(!ReadFile(hFile, (LPBYTE)lpbi, sizeof(BITMAPINFOHEADER), &dwRead, NULL))
		goto ErrExit;

	if(sizeof(BITMAPINFOHEADER) != dwRead)
		goto ErrExit;
	
	//检查是否是Windows下的位图文件
	if(lpbi->biSize == sizeof(BITMAPCOREHEADER))
		goto ErrExit;
	
	//决定颜色表大小并读入
	if(!(nNumColors = (UINT)lpbi->biClrUsed))
	{
		if(lpbi->biBitCount != 24)
			nNumColors=1<<lpbi->biBitCount;
	}
	
	//如果某些属性值为0,则为这些属性设置缺省值
	if(lpbi->biClrUsed == 0)
		lpbi->biClrUsed = nNumColors;
	if(lpbi->biSizeImage == 0)
	{
		lpbi->biSizeImage = ((((lpbi->biWidth*(DWORD)lpbi->biBitCount)+31)&~31)>>3)*lpbi->biHeight;
	}
	
	//重新为文件头和颜色表分配内存
	GlobalUnlock(hDib);
	hDibtmp = GlobalReAlloc(hDib, lpbi->biSize+nNumColors*sizeof(RGBQUAD)+lpbi->biSizeImage,0);
	
	if(!hDibtmp)
		goto ErrExitNoUnlock;
	else
		hDib = hDibtmp;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
	
	//从文件中读入颜色表内容
	ReadFile(hFile, (LPBYTE)(lpbi)+lpbi->biSize, nNumColors*sizeof(RGBQUAD), &dwRead, NULL);
	
	//从文件头开始到真正图像信息的偏移量
	offBits = lpbi->biSize+nNumColors*sizeof(RGBQUAD);
	
	//找到图像信息的起始地址并读入
	if(bmfHeader.bfOffBits != 0L)
		SetFilePointer(hFile,bmfHeader.bfOffBits,NULL,FILE_BEGIN);
	if(ReadFile(hFile,(LPBYTE)lpbi+offBits,lpbi->biSizeImage,&dwRead,NULL))
		goto OKExit;

ErrExit:
	GlobalUnlock(hDib);
	return NULL;
ErrExitNoUnlock:
	GlobalFree(hDib);
	return NULL;
OKExit:
	GlobalUnlock(hDib);
	return hDib;

}
/******************************************************
load the specified DIB from a file,allocate memory
for it,and read the disk file into the memoty.
parameter:     LPTSTR lpFileName	--文件名
return:        HANDLE				--DIB块的句柄
call:          HANDLE ReadDIBFile(HANDLE)
******************************************************/
HDIB LoadDIB(LPCTSTR lpFileName)
{
	HDIB hDib;
	HANDLE hFile;
	
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	 
	if((hFile = CreateFile(	lpFileName, 
							GENERIC_READ, 
							FILE_SHARE_READ, 
							NULL, 
							OPEN_EXISTING,
							FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,
							NULL))
						!=INVALID_HANDLE_VALUE)
	{
		hDib = ReadDIBFile(hFile);
		CloseHandle(hFile);
		SetCursor(LoadCursor(NULL,IDC_ARROW));
		return hDib;
	}
	else
	{
		SetCursor(LoadCursor(NULL,IDC_ARROW));
		return NULL;
	}
}
/***************************************************
load DIB from resource.
parameter:    LPTSTR(point to DIB)
return:       LPBYTE(to DIB bits)
***************************************************/
LPBYTE LoadDIBFromResource(LPCTSTR lpszBitmap)
{
	HINSTANCE hInst = AfxGetInstanceHandle();
	HRSRC hRes = ::FindResource(hInst, lpszBitmap, "DIB");

	if(hRes == NULL)
		return NULL;
	HGLOBAL hData = ::LoadResource(hInst,hRes);
	return (LPBYTE)::LockResource(hData);

}
/********************************************
save the specified DIB into the specified 
file name on disk.if the file already exists,
it will be overwritten.
input:	HDIB hDib			--DIB句柄
		LPCTSTR lpFileName	--要存为的文件名
output:	bool				--操作是否成功
********************************************/
BOOL SaveDIB(HDIB hDib, LPCTSTR lpFileName)
{
	BITMAPFILEHEADER	bmfHeader;	//Bitmap的文件头
	LPBITMAPINFOHEADER	lpbi;		
	HANDLE				hFile;
	DWORD				dwDibsize;
	DWORD				dwWritten;

	if(!hDib)
		return FALSE;

	//创建一个文件得到其控制句柄
	hFile=CreateFile(	lpFileName,
						GENERIC_WRITE,
						0,
						NULL,
						CREATE_ALWAYS,
						FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,
						NULL);

	if(hFile == INVALID_HANDLE_VALUE)
		return FALSE;

	//得到指向BITMAPINFOHEADER的指针并检查其合法性
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
	if(!lpbi)
	{
		CloseHandle(hFile);
		return FALSE;
	}
	if(lpbi->biSize != sizeof(BITMAPINFOHEADER))
	{
		GlobalUnlock(hDib);
		CloseHandle(hFile);

⌨️ 快捷键说明

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