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 + -
显示快捷键?