📄 dibapi.cpp
字号:
switch(wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
/************************************************************
*
*函数名称:
* CopyHandle()
*
*参数:
* HGLOBAL h -要复制的内存区域
*
* 返回值:
* HGLOBAL -复制后的新内存区域
*
*说明:
* 该函数复制指定的内存区域。返回复制后的新内存区域,出错时返回0。
*
*
***************************************************************/
HGLOBAL WINAPI CopyHandle(HGLOBAL h)
{
if(h==NULL)
return NULL;
// 获取指定内存区域大小
DWORD dwLen= ::GlobalSize((HGLOBAL)h);
//分配新内存空间
HGLOBAL hCopy = ::GlobalAlloc(GHND,dwLen);
//判断分配是否成功
if(hCopy!=NULL)
{
//锁定
void *lpCopy = ::GlobalLock((HGLOBAL)hCopy);
void *lp =::GlobalLock((HGLOBAL)h);
//复制
memcpy(lpCopy,lp,dwLen);
//解除锁定
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
}
return hCopy;
}
/************************************************************
*
*函数名称:
* SaveDIB()
*
*参数:
* HDIB hDib - 要保存的DIB
* CFill &file - 保存文件CFile
* 返回值:
* BOOL -成功返回TRUE,否则返回FALSE或则CfileException
*
*说明:
* 该函数将指定的DIB对象保存到指定的CFile中。该CFile由调用程序
*打开和关闭
*
*
***************************************************************/
BOOL WINAPI SaveDIB(HDIB hDib,CFile& file)
{
//Bitmap文件头
BITMAPFILEHEADER bmfHdr;
//指向BITMAPINFOHEADER的指针
LPBITMAPINFOHEADER lpBI;
//DIB大小
DWORD dwDIBSize;
if(hDib==NULL)
{
//如果DIB为空,返回FALSE
return FALSE;
}
//读取BITMAPINFO结构,并锁定
lpBI = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);
if(lpBI == NULL)
{
//为空,返回FALSE
return FALSE;
}
//判断是否是WIN 3.0DIB
if(!IS_WIN30_DIB(lpBI))
{
//不支持其他类型的DIB保存
//解除锁定
::GlobalUnlock((HGLOBAL)hDib);
//返回FALSE
return FALSE;
}
//填充文件头
//文件类型“BM”
bmfHdr.bfType = DIB_HEADER_MARKER;
//计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是
//全局内存大小并不是DIB真正的大小,他总是多几个字节。
//这样就需要计算一下DIB的真实大小。
//文件头大小+颜色表大小
//(BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DIB的真实大小
dwDIBSize = *(LPDWORD)lpBI+::PaletteSize((LPSTR)lpBI);
//计算图象大小
if((lpBI->biCompression == BI_RLE8)||(lpBI->biCompression == BI_RLE4))
{
//对于RLE位图,没法计算大小,只能信任biSizeImage内的值
dwDIBSize+= lpBI->biSizeImage;
}
else
{
//象素的大小
DWORD dwBmBitsSize;
//大小为Width*Height
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))
*lpBI->biHeight;
//计算出DIB真正的大小
dwDIBSize+=dwBmBitsSize;
//更新biSizeImage( 很多BMP文件头中biSizeImage的值是错误的)
lpBI->biSizeImage = dwBmBitsSize;
}
//计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
bmfHdr.bfSize = dwDIBSize +sizeof(BITMAPFILEHEADER);
//两个保留字
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
//计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB大小
//+颜色表大小
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+lpBI->biSize
+PaletteSize((LPSTR)lpBI);
//尝试写文件
TRY
{
//写文件头
file.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER));
//写DIB头和象素
file.WriteHuge(lpBI,dwDIBSize);
}
CATCH(CFileException,e)
{
//解除锁定
::GlobalUnlock((HGLOBAL)hDib);
//抛出异常
THROW_LAST();
}
END_CATCH
//解除锁定
::GlobalUnlock((HGLOBAL)hDib);
//返回TRUE
return TRUE;
}
/************************************************************
*
*函数名称:
* ReadDIBFile()
*
*参数:
*
* CFill &file - 要读取文件的文件CFile
* 返回值:
* HDIB -成功返回DIB句柄,否则返回NULL
*
*说明:
* 该函数将指定的文件中的DIB对象读到指定的内存区域中。
*除BITMAPFILEHEADER外的内容都将被读入内存。
*
*
***************************************************************/
HDIB WINAPI ReadDIBFile(CFile& file)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
HDIB hDIB;
LPSTR pDIB;
//获取DIB(文件)长度(字节)
dwBitsSize = file.GetLength();
//尝试读取DIB文件头
if(file.Read((LPSTR)&bmfHeader,sizeof(bmfHeader))!=sizeof(bmfHeader))
{
//大小不对,返回NULL
return NULL;
}
//判断是否是DIB对象,检查头两个字节是否是‘BM’
if(bmfHeader.bfType!=DIB_HEADER_MARKER)
{
//非DIB对象,返回NULL
return NULL;
}
//为DIB分配内存
hDIB =(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,dwBitsSize);
if(hDIB == 0)
{
//内存分配失败,返回NULL
return NULL;
}
//锁定
pDIB =(LPSTR)::GlobalLock((HGLOBAL)hDIB);
//读象素
if(file.ReadHuge(pDIB,dwBitsSize - sizeof(BITMAPFILEHEADER))!= dwBitsSize -sizeof(BITMAPFILEHEADER))
{
//大小不对
//解除锁定
::GlobalUnlock((HGLOBAL)hDIB);
//释放内存
::GlobalFree((HGLOBAL)hDIB);
//返回NULL
return NULL;
}
//解除锁定
::GlobalUnlock((HGLOBAL)hDIB);
//返回DIB句柄
return hDIB;
}
/************************************************************
*
*函数名称:
* LinerTrans()
*
*参数:
*
* LPSTR lpDIBBits -指向原DIB图象指针
* LONG lWidth -原图象宽度(象素数)
* LONG lHeight -原图象高度(象素数)
* FLOAT fA -线性变换斜率
* FLOAT fB -线性变换截距
* 返回值:
* BOOL -成功返回TRUE,否则返回FALSE
*
*说明:
* 该函数用来对图象进行灰度的线性变换操作
*
*
***************************************************************/
BOOL WINAPI LinerTrans(LPSTR lpDIBBits,LONG lWidth,LONG lHeight,FLOAT fA,FLOAT fB)
{
//指向原图的指针
unsigned char* lpSrc;
//循环变量
LONG i;
LONG j;
//图象每行的字节数
LONG lLineBytes;
//中间变量
FLOAT fTemp;
//计算图象每行的字节数
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;
//线性变换
fTemp = fA*(*lpSrc)+fB;
//判断是否超出范围
if(fTemp >255)
{
//直接附值为255
*lpSrc = 255;
}
else if (fTemp<0)
{
//直接赋值为0
*lpSrc = 0;
}
else
{
//四舍五入
*lpSrc = (unsigned char)(fTemp+0.5);
}
}
}
//返回
return TRUE;
}
/************************************************************
*
*函数名称:
* ThresholdTrans()
*
*参数:
*
* LPSTR lpDIBBits -指向原DIB图象指针
* LONG lWidth -原图象宽度(象素数)
* LONG lHeight -原图象高度(象素数)
* BYTE bThre -阀值
* 返回值:
* BOOL -成功返回TRUE,否则返回FALSE
*
*说明:
* 该函数用来对图象进行阀值变换,对于灰度小于阀值的象素直接
* 设置灰度为0;灰度值大于阀值的象素直接设置为255。
*
***************************************************************/
BOOL WINAPI ThresholdTrans(LPSTR lpDIBBits,LONG lWidth,LONG lHeight,BYTE bThre)
{
//指向原图象的指针
unsigned char* lpSrc;
//循环变量
LONG i;
LONG j;
//图象每行的字节数
LONG lLineBytes;
//计算图象每行的字节数
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;
//判断是否小于阀值
if((*lpSrc)<bThre)
{
//直接赋为0
*lpSrc=0;
}
else
{
//直接赋为255
*lpSrc=255;
}
}
}
//返回
return TRUE;
}
/************************************************************
*
*函数名称:
* WindowTrans()
*
*参数:
*
* LPSTR lpDIBBits -指向原DIB图象指针
* LONG lWidth -原图象宽度(象素数)
* LONG lHeight -原图象高度(象素数)
* BYTE bLow -窗口下限
* BYTE bUp -窗口上限
* 返回值:
* BOOL -成功返回TRUE,否则返回FALSE
*
*说明:
* 该函数用来对图象进行窗口变换,只要在窗口范围内的灰度保持不
*变,小于下限的象素直接设置灰度值为0,大于上限的象素直接设置
*灰度值为255。
***************************************************************/
BOOL WINAPI WindowTrans(LPSTR lpDIBBits,LONG lWidth,LONG lHeight,BYTE bLow,BYTE bUp)
{
//指向原图象的指针
unsigned char* lpSrc;
//循环变量
LONG i;
LONG j;
//图象每行的字节数
LONG lLineBytes;
//计算图象每行的字节数
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;
//判断是否超出范围
if((*lpSrc)<bLow)
{
//直接赋值为0
*lpSrc=0;
}
else if((*lpSrc)>bUp)
{
//直接赋值为255
*lpSrc=255;
}
}
}
//返回
return TRUE;
}
/************************************************************
*
*函数名称:
* ThresholdTrans()
*
*参数:
*
* LPSTR lpDIBBits -指向原DIB图象指针
* LONG lWidth -原图象宽度(象素数)
* LONG lHeight -原图象高度(象素数)
* BYTE bX1 -灰度拉伸第一个点的X坐标
* BYTE bY1 -灰度拉伸第一个点的Y坐标
* BYTE bX2 -灰度拉伸第二个点的X坐标
* BYTE bY2 -灰度拉伸第二个点的Y坐标
* 返回值:
* BOOL -成功返回TRUE,否则返回FALSE
*
*说明:
* 该函数用来对图象进行灰度拉伸
*
***************************************************************/
BOOL WINAPI GrayStretch(LPSTR lpDIBBits,LONG lWidth,LONG lHeight,BYTE bX1,BYTE bY1,BYTE bX2,BYTE bY2)
{
//指向原图象的指针
unsigned char* lpSrc;
//循环变量
LONG i;
LONG j;
//灰度映射表
BYTE bMap[256];
//图象每行的字节数
BYTE lLineBytes;
//计算图象每行的字符数
lLineBytes = WIDTHBYTES(lWidth*8);
//计算灰度映射表
for(i=0;i<=bX1;i++)
{
//判断bX1是否大于0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -