📄 dibapi.cpp
字号:
}
//填充文件头
//文件类型“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
if(bX1>0)
{
//线性变换
bMap[i]=(BYTE)bY1*i/bX1;
}
else
{
//直接附值为0
bMap[i]=0;
}
}
for(;i<bX2;i++)
{
//判断bX1是否等于bX2
if(bX2!=bX1)
{
//线性变换
bMap[i]=bY1+(BYTE)((bY2-bY1)*(i-bX1)/(bX2-bX1));
}
else
{
//直接附值为bY1
bMap[i]=bY1;
}
}
for(;i<256;i++)
{
//判断bX2是否等于255
if(bX2!=255)
{
//线性变换
bMap[i]=bY2+(BYTE)((255-bY2)*(i-bX2)/(255-bX2));
}
else
{
//直接附值为255
bMap[i]=255;
}
}
//每行
for(i=0;i<lHeight;i++)
{
//每列
for(j=0;j<lWidth;j++)
{
//指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-i)+j;
//计算新的灰度值
*lpSrc = bMap[*lpSrc];
}
}
//返回
return TRUE;
}
/************************************************************
*
*函数名称:
* InteEqualize()
*
*参数:
*
* LPSTR lpDIBBits -指向原DIB图象指针
* LONG lWidth -原图象宽度(象素数)
* LONG lHeight -原图象高度(象素数)
* 返回值:
* BOOL -成功返回TRUE,否则返回FALSE
*
*说明:
* 该函数用来对图象进行直方图均衡
***************************************************************/
BOOL WINAPI InteEqualize(LPSTR lpDIBBits,LONG lWidth,LONG lHeight)
{
//指向原图象的指针
unsigned char* lpSrc;
//临时变量
LONG lTemp;
//循环变量
LONG i;
LONG j;
//灰度映射表
BYTE bMap[256];
//图象每行的字节数
LONG lCount[256];
//图象每行的字节数
LONG lLineBytes ;
//计算图象每行的字节数
lLineBytes = WIDTHBYTES(lWidth*8);
//重置记数为0
for(i=0;i<lHeight;i++)
{
for(j=0;j<lWidth;j++)
{
lpSrc=(unsigned char*)lpDIBBits+lLineBytes*i+j;
//记数加1
lCount[*(lpSrc)]++;
}
}
for(i=0;i<256;i++)
{
//初始为0
lTemp=0;
for(j=0;j<=i;j++)
{
lTemp+=lCount[j];
}
//计算对应的新灰度值
bMap[i]=(BYTE)(lTemp * 255/lHeight/lWidth);
}
//每行
for(i=0;i<lHeight;i++)
{
for(j=0;j<lWidth;j++)
{
//指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)(lpDIBBits+lLineBytes*(lHeight-1-i)+j);
//计算新的灰度值
*lpSrc = bMap[*lpSrc];
}
}
return TRUE;
}
/************************************************************
*
*函数名称:
* ChaosEncode()
*
*参数:
*
* LPSTR lpDIBBits -指向原DIB图象指针
* LONG lWidth -原图象宽度(象素数)
* LONG lHeight -原图象高度(象素数)
*
* 返回值:
* BOOL -成功返回TRUE,否则返回FALSE
*
*说明:
* 该函数用来对图象进行混沌加密
***************************************************************/
BOOL WINAPI ChaosEncode(LPSTR lpDIBBits,LONG lWidth,LONG lHeight,double Xstart,double a)
{
//指向原图的指针
unsigned char* lpSrc;
//保存的混沌密码序列
DWORD chaos,k;
double x,y;
x=Xstart;
//循环变量
LONG i;
LONG j;
LONG h=1000;
LONG w;
//图象每行的字节数
LONG lLineBytes;
//中间变量
//FLOAT fTemp;
//计算图象每行的字节数
lLineBytes = WIDTHBYTES(lWidth*8);
for(w=0;w<1000;w++)
{
y=a*x*(1-x);
x=y;
}
//循环次数
//for(h=0;h<100;h++)
//{
//while(h>0)
//{
//每行
for(i=0;i<lHeight;i++)
{
//每列
for(j=0;j<lWidth;j++)
{
//指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-i)+j;
chaos=0;
for(w=0;w<8;w++)
{
y=a*x*(1-x);
if(y >= 0.4)
{
k=1;
}
else
{
k=0;
}
chaos=((chaos<<1)|k);
// if(chaos>(int)256*y)
//chaos=256-chaos;
x=y;
//可以做个数组,进行
}
*lpSrc=(unsigned char)((int)(*lpSrc)^(int)(chaos));
//*lpSrc=255;
//chaos = ::LogisticCode(x,a);
//AfxMessageBox(chaos);
//fTemp = *lpSrc;
//判断是否超出范围
/*if(fTemp >255)
{
//直接附值为255
*lpSrc = 255;
}
else if (fTemp<0)
{
//直接赋值为0
*lpSrc = 0;
}
else
{
//四舍五入
*lpSrc = (unsigned char)(fTemp+0.5);
}*/
h--;
}
}
//}
//返回
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -