8种常用图像处理算法

fdmworld 贡献于2012-04-09

作者 cjz  创建于2010-12-14 14:50:00   修改者微软用户  修改于2010-12-14 14:50:00字数20246

文档摘要:8种常用图像处理算法(函数)
关键词:

 8种常用图像处理算法(函数) ------以下所有函数均放在CimageProcessingView.ccp下 1.图像镜像 void CCimageProcessingView::OnGeomTrpo() { //获取指向文档的指针 CCimageProcessingDoc* pDoc = GetDocument(); //指向DIB的指针 LPSTR lpDIB; //锁定DIB lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); //设置光标状态为等待状态 BeginWaitCursor(); //调用VertMirror函数镜像图象 if (VertMirror(lpDIB)) { //设置文档修改标记 pDoc->SetModifiedFlag(TRUE); //更新所有视图 pDoc->UpdateAllViews(NULL); } else { //提示信息 MessageBox("实现图象镜像失败!"); } //解除锁定 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); //结束光标等待状态 EndWaitCursor(); } /************************************************************************* * * 函数名称: * * VertMirror() * * 参数: * * LPSTR lpDIB //指向源DIB图像指针 * * 返回值: * * BOOL //镜像成功返回TRUE,否则返回FALSE。 * * 说明: * * 该函数用来实现DIB图像的垂直镜像。 * ************************************************************************/ BOOL WINAPI VertMirror(LPSTR lpDIB) { //原图象宽度 LONG lWidth; //原图象高度 LONG lHeight; //原图象的颜色数 WORD wNumColors; //原图象的信息头结构指针 LPBITMAPINFOHEADER lpbmi; //指向原图象和目的图象的像素的指针 LPBYTE lpSrc,lpDst; //平移后剩余图像在源图像中的位置(矩形区域) CRect rectSrc; //指向原图像像素的指针 LPBYTE lpDIBBits; //指向复制图像像素的指针 LPBYTE lpNewDIBBits; //内存句柄 HLOCAL h; //循环变量 LONG i; //图像每行的字节数 LONG lLineBytes; //获取图象的信息头结构的指针 lpbmi=(LPBITMAPINFOHEADER)lpDIB; //找到图象的像素位置 lpDIBBits=(LPBYTE)::FindDIBBits(lpDIB); //获取图象的宽度 lWidth=::DIBWidth(lpDIB); //获取图象的高度 lHeight=::DIBHeight(lpDIB); //获取图象的颜色数 wNumColors=::DIBNumColors(lpDIB); //计算图像每行的字节数 lLineBytes = WIDTHBYTES(lWidth *(lpbmi->biBitCount)); // 暂时分配内存,以保存新图像 h= LocalAlloc(LHND, lLineBytes); // 分配内存失败,直接返回 if (!h) return FALSE; // 锁定内存 lpNewDIBBits = (LPBYTE)LocalLock(h); //如果是256色位图或真彩色位图 if(wNumColors==256||wNumColors==0) { //平移图像,每次移动一行 for(i = 0; iGetHDIB()); // 缩放比率 int iRotaAngle; // 创建对话框 CDlgGeoRota dlgPara; // 初始化变量值 dlgPara.m_iRotaAngle = 90; // 显示对话框,提示用户设定旋转角度 if (dlgPara.DoModal() != IDOK) { // 返回 return; } // 获取用户设定的平移量 iRotaAngle = dlgPara.m_iRotaAngle; // 删除对话框 delete dlgPara; //创建新DIB HDIB hNewDIB=NULL; //设置光标状态为等待状态 BeginWaitCursor(); //调用RotateDIB函数旋转DIB图象 hNewDIB=(HDIB)::RotateDIB(lpDIB,iRotaAngle); //旋转成功 if (hNewDIB) { //替换原来的DIB图象为新的DIB pDoc->ReplaceHDIB(hNewDIB); //更新DIB图象的大小和调色板 pDoc->InitDIBData(); //设置文档修改标记 pDoc->SetModifiedFlag(TRUE); //调节滚动视图大小 SetScrollSizes(MM_TEXT,pDoc->GetDocSize()); //更新所有视图 pDoc->UpdateAllViews(NULL); } else { //提示信息 MessageBox("实现图象旋转失败!"); } //解除锁定 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); //结束光标等待状态 EndWaitCursor(); } /************************************************************************* * * 函数名称: * * RotateDIB () * * 参数: * * LPSTR lpDIB //指向源DIB图像指针 * * int iAngle * 说明: * * 该函数用来实现DIB图像的旋转。 * ************************************************************************/ HGLOBAL WINAPI RotateDIB(LPSTR lpDIB,int iAngle) { //原图象宽度 LONG lWidth; //原图象高度 LONG lHeight; //旋转后图象宽度 LONG lNewWidth; //旋转后图象高度 LONG lNewHeight; //原图象的颜色数 WORD wNumColors; //原图象的信息头结构指针 LPBITMAPINFOHEADER lpbmi,lpbmi0; //指向原图象和目的图象的像素的指针 LPBYTE lpSrc,lpDst; //指向原图像像素的指针 LPBYTE lpDIBBits; //指向旋转后图像(像素)的指针 LPBYTE lpNewDIBBits; LPSTR lpNewDIB; //旋转后新的DIB句柄 HDIB hDIB; //循环变量 LONG i,j,i0,j0; //原图像每行的字节数 LONG lLineBytes; //旋转后图像每行的字节数 LONG lNewLineBytes; //旋转角度的弧度 double fArcAngle; //旋转角度的正弦和余弦 float fSin,fCos; //旋转前图象四个角的坐标(以图象中心为坐标系原点) float fSrcX1,fSrcY1,fSrcX2,fSrcY2; float fSrcX3,fSrcY3,fSrcX4,fSrcY4; //旋转后图象四个角的坐标(以图象中心为坐标系原点) float fDstX1,fDstY1,fDstX2,fDstY2; float fDstX3,fDstY3,fDstX4,fDstY4; //两个中间量 float f1,f2; //找到图象的像素位置 lpDIBBits=(LPBYTE)::FindDIBBits(lpDIB); //获取图象的宽度 lWidth=::DIBWidth(lpDIB); //获取图象的高度 lHeight=::DIBHeight(lpDIB); //获取图象的颜色数 wNumColors=::DIBNumColors(lpDIB); //获取指向原位图信息头结构的指针 lpbmi0=(LPBITMAPINFOHEADER)lpDIB; //计算原图像每行的字节数 lLineBytes = WIDTHBYTES(lWidth *(lpbmi0->biBitCount)); //将旋转角度从度转换到弧度 fArcAngle =(iAngle*PI)/180.0; //计算旋转角度的正弦 fSin = (float) sin(fArcAngle); //计算旋转角度的余弦 fCos = (float) cos(fArcAngle); //计算原图的四个角的坐标(以图像中心为坐标系原点) fSrcX1 = (float) (- (lWidth - 1) / 2); fSrcY1 = (float) ( (lHeight - 1) / 2); fSrcX2 = (float) ( (lWidth - 1) / 2); fSrcY2 = (float) ( (lHeight - 1) / 2); fSrcX3 = (float) (- (lWidth - 1) / 2); fSrcY3 = (float) (- (lHeight - 1) / 2); fSrcX4 = (float) ( (lWidth - 1) / 2); fSrcY4 = (float) (- (lHeight - 1) / 2); //计算新图四个角的坐标(以图像中心为坐标系原点) fDstX1 = fCos * fSrcX1 + fSin * fSrcY1; fDstY1 = -fSin * fSrcX1 + fCos * fSrcY1; fDstX2 = fCos * fSrcX2 + fSin * fSrcY2; fDstY2 = -fSin * fSrcX2 + fCos * fSrcY2; fDstX3 = fCos * fSrcX3 + fSin * fSrcY3; fDstY3 = -fSin * fSrcX3 + fCos * fSrcY3; fDstX4 = fCos * fSrcX4 + fSin * fSrcY4; fDstY4 = -fSin * fSrcX4 + fCos * fSrcY4; //计算旋转后的图像实际宽度 lNewWidth = (LONG) ( max( fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2) ) + 0.5); //计算旋转后的图像高度 lNewHeight = (LONG) ( max( fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2) ) + 0.5); //计算旋转后图像每行的字节数 lNewLineBytes = WIDTHBYTES(lNewWidth * lpbmi0->biBitCount); //计算两个常数 f1 = (float) (-0.5 * (lNewWidth - 1) * fCos - 0.5 * (lNewHeight - 1) * fSin + 0.5 * (lWidth - 1)); f2 = (float) ( 0.5 * (lNewWidth - 1) * fSin - 0.5 * (lNewHeight - 1) * fCos + 0.5 * (lHeight - 1)); //暂时分配内存,以保存新图像 hDIB=(HDIB)::GlobalAlloc(GHND, lNewHeight*lNewLineBytes+ *(LPDWORD)lpDIB+::PaletteSize(lpDIB)); //分配内存失败,直接返回 if (!hDIB) return NULL; //锁定内存 lpNewDIB = (LPSTR)::GlobalLock((HGLOBAL)hDIB); //复制DIB信息头和调色板 memcpy(lpNewDIB,lpDIB,*(LPDWORD)lpDIB+::PaletteSize(lpDIB)); //获取图象的信息头结构的指针 lpbmi=(LPBITMAPINFOHEADER)lpNewDIB; //更新DIB图象的高度和宽度 lpbmi->biWidth=lNewWidth; lpbmi->biHeight=lNewHeight; //找到新DIB像素的起始位置 lpNewDIBBits=(LPBYTE)::FindDIBBits(lpNewDIB); //如果是256色位图 if(wNumColors==256) { //旋转后图像每行 for(i = 0; i= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)) { // 指向源DIB图象第i0行,第j0个象素的指针 lpSrc = (LPBYTE)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0; // 复制象素 *lpDst = *lpSrc; } else { // 对于源图中没有的象素,直接赋值为255 * ((LPBYTE)lpDst) = 255; } } } } //如果是24位真彩色位图 else if(wNumColors==0) { //旋转后图像每行 for(i = 0; i= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)) { // 指向源DIB图象第i0行,第j0个象素的指针 lpSrc = (LPBYTE)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + 3*j0; // 复制象素 memcpy(lpDst,lpSrc,3); } else { // 对于源图中没有的象素,直接赋值为255 memset(lpDst,255,3); } } } } else { AfxMessageBox("只支持256色和真彩色位图"); // 释放内存 GlobalUnlock(hDIB); GlobalFree(hDIB); return NULL; } // 返回 return hDIB; } 3.图像缩放(对话框自己建立) void CCimageProcessingView::OnGeomZoom() { // TODO: Add your command handler code here // 图像缩放 // 获取文档 CCimageProcessingDoc* pDoc = GetDocument(); // 指向DIB的指针 LPSTR lpDIB; // 锁定DIB lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); // 缩放比率 float fXZoomRatio; float fYZoomRatio; // 创建对话框 CDlgGeoZoom dlgPara; // 初始化变量值 dlgPara.m_XZoom = 0.5; dlgPara.m_YZoom = 0.5; // 显示对话框,提示用户设定平移量 if (dlgPara.DoModal() != IDOK) { // 返回 return; } // 获取用户设定的平移量 fXZoomRatio = dlgPara.m_XZoom; fYZoomRatio = dlgPara.m_YZoom; // 删除对话框 delete dlgPara; // 创建新DIB HDIB hNewDIB = NULL; // 更改光标形状 BeginWaitCursor(); // 调用ZoomDIB()函数转置DIB hNewDIB = (HDIB) ZoomDIB(lpDIB, fXZoomRatio, fYZoomRatio); // 判断缩放是否成功 if (hNewDIB != NULL) { // 替换DIB,同时释放旧DIB对象 pDoc->ReplaceHDIB(hNewDIB); // 更新DIB大小和调色板 pDoc->InitDIBData(); // 设置脏标记 pDoc->SetModifiedFlag(TRUE); // 重新设置滚动视图大小 SetScrollSizes(MM_TEXT, pDoc->GetDocSize()); // 更新视图 pDoc->UpdateAllViews(NULL); } else { // 提示用户 MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK); } // 解除锁定 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); // 恢复光标 EndWaitCursor(); } /************************************************************************* * * 函数名称: * ZoomDIB() * * 参数: * LPSTR lpDIB - 指向源DIB的指针 * float fXZoomRatio - X轴方向缩放比率 * float fYZoomRatio - Y轴方向缩放比率 * * 返回值: * HGLOBAL - 缩放成功返回新DIB句柄,否则返回NULL。 * * 说明: * 该函数用来缩放DIB图像,返回新生成DIB的句柄。 * ************************************************************************/ HGLOBAL WINAPI ZoomDIB(LPSTR lpDIB, float fXZoomRatio, float fYZoomRatio) { // 源图像的宽度和高度 LONG lWidth; LONG lHeight; // 缩放后图像的宽度和高度 LONG lNewWidth; LONG lNewHeight; WORD wNumColors; // 缩放后图像的宽度(lNewWidth',必须是4的倍数) LONG lNewLineBytes; // 指向源图像的指针 LPBYTE lpDIBBits; // 指向源象素的指针 LPBYTE lpSrc; // 缩放后新DIB句柄 HDIB hDIB; // 指向缩放图像对应象素的指针 LPBYTE lpDst; // 指向缩放图像的指针 LPSTR lpNewDIB; LPBYTE lpNewDIBBits; // 指向BITMAPINFO结构的指针(Win3.0) LPBITMAPINFOHEADER lpbmi,lpbmi0; // 指向BITMAPCOREINFO结构的指针 LPBITMAPCOREHEADER lpbmc; // 循环变量(象素在新DIB中的坐标) LONG i; LONG j; // 象素在源DIB中的坐标 LONG i0; LONG j0; // 图像每行的字节数 LONG lLineBytes; // 找到源DIB图像象素起始位置 lpDIBBits = (LPBYTE)::FindDIBBits(lpDIB); // 获取图像的宽度 lWidth = ::DIBWidth(lpDIB); // 获取图像的高度 lHeight = ::DIBHeight(lpDIB); wNumColors= ::DIBNumColors(lpDIB); lpbmi0=(LPBITMAPINFOHEADER)lpDIB; // 计算图像每行的字节数 lLineBytes = WIDTHBYTES(lWidth * (lpbmi0->biBitCount)); // 计算缩放后的图像实际宽度 // 此处直接加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分 lNewWidth = (LONG) (lWidth* fXZoomRatio + 0.5); // 计算新图像每行的字节数 lNewLineBytes = WIDTHBYTES(lNewWidth * (lpbmi0->biBitCount)); // 计算缩放后的图像高度 lNewHeight = (LONG) (lHeight * fYZoomRatio + 0.5); // 分配内存,以保存新DIB hDIB = (HDIB) ::GlobalAlloc(GHND, lNewLineBytes * lNewHeight + *(LPDWORD)lpDIB + ::PaletteSize(lpDIB)); // 判断是否内存分配失败 if (hDIB == NULL) { // 分配内存失败 return NULL; } // 锁定内存 lpNewDIB = (LPSTR)::GlobalLock((HGLOBAL) hDIB); // 复制DIB信息头和调色板 memcpy(lpNewDIB, lpDIB, *(LPDWORD)lpDIB + ::PaletteSize(lpDIB)); // 找到新DIB象素起始位置 lpNewDIBBits = (LPBYTE)::FindDIBBits(lpNewDIB); // 获取指针 lpbmi = (LPBITMAPINFOHEADER)lpNewDIB; lpbmc = (LPBITMAPCOREHEADER)lpNewDIB; // 更新DIB中图像的高度和宽度 if (IS_WIN30_DIB(lpNewDIB)) { // 对于Windows 3.0 DIB lpbmi->biWidth = lNewWidth; lpbmi->biHeight = lNewHeight; } else { // 对于其它格式的DIB lpbmc->bcWidth = (unsigned short) lNewWidth; lpbmc->bcHeight = (unsigned short) lNewHeight; } if(wNumColors==256) { // 针对图像每行进行操作 for(i = 0; i < lNewHeight; i++) { // 针对图像每列进行操作 for(j = 0; j < lNewWidth; j++) { // 指向新DIB第i行,第j个象素的指针 // 注意此处宽度和高度是新DIB的宽度和高度 lpDst = (LPBYTE)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + j; // 计算该象素在源DIB中的坐标 i0 = (LONG) (i / fYZoomRatio + 0.5); j0 = (LONG) (j / fXZoomRatio + 0.5); // 判断是否在源图范围内 if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)) { // 指向源DIB第i0行,第j0个象素的指针 lpSrc = (LPBYTE)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0; // 复制象素 *lpDst = *lpSrc; } else { // 对于源图中没有的象素,直接赋值为255 * ((LPBYTE)lpDst) = 255; } } } } else if(wNumColors==0) {for(i = 0; i < lNewHeight; i++) { // 针对图像每列进行操作 for(j = 0; j < lNewWidth; j++) { // 指向新DIB第i行,第j个象素的指针 // 注意此处宽度和高度是新DIB的宽度和高度 lpDst = (LPBYTE)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + 3*j; // 计算该象素在源DIB中的坐标 i0 = (LONG) (i / fYZoomRatio + 0.5); j0 = (LONG) (j / fXZoomRatio + 0.5); // 判断是否在源图范围内 if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)) { // 指向源DIB第i0行,第j0个象素的指针 lpSrc = (LPBYTE)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + 3*j0; // 复制象素 memcpy(lpDst,lpSrc,3); } else { // 对于源图中没有的象素,直接赋值为255 memset(lpDst,255,3); } } } } // 返回 return hDIB; } 4. 256位图=》灰度图 /************************************************************************* * * 函数名称: * On256tograyscale () * * 说明: * 该算法函数用来把256图像转化成灰度图像。 * ************************************************************************/ void CCimageProcessingView::On256tograyscale() { // TODO: Add your command handler code here // 获取文档指针 CCimageProcessingDoc* pDoc = GetDocument(); // 指向DIB的指针 LPSTR lpDIB; // 指向DIB象素指针 LPSTR lpDIBBits; // 指向DIB的一个象素的指针 BYTE * lpSrc; // 颜色表中的颜色数目 WORD wNumColors; // 灰度映射表 BYTE bGrayMap[256]; //调色板索应循环变量 LONG i; // 图象高度循环变量 LONG ih; //图象宽度循环变量 LONG iw; // 图像宽度 LONG lWidth; // 图像高度 LONG lHeight; // 图像每行的字节数 LONG OneLineBytes; // 指向BITMAPINFO结构的指针(Win3.0) LPBITMAPINFO lpbmi; // 指向BITMAPCOREINFO结构的指针(OS/2) LPBITMAPCOREINFO lpbmc; // 表明是否是Win3.0 DIB的标记 BOOL bWin30DIB; lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); // 获取指向BITMAPINFO结构的指针(Win3.0) lpbmi = (LPBITMAPINFO)lpDIB; // 获取指向BITMAPCOREINFO结构的指针(OS/2) lpbmc = (LPBITMAPCOREINFO)lpDIB; // 锁定DIB // 获取DIB中颜色表中的颜色数目 wNumColors = ::DIBNumColors(lpDIB); // 判断是否是256色位图 if (wNumColors != 256) { MessageBox("不是256色位图!"); // 解除锁定 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); // 返回 return; } // 更改光标形状 BeginWaitCursor(); // 判断是否是WIN3.0的DIB bWin30DIB = IS_WIN30_DIB(lpDIB); //将原图象的调色板转化为灰度调色板 //建立原调色板索引与灰度调色板索引的映射关系 for (i = 0; i < 256; i ++) { if (bWin30DIB) { //对原256色调色板的每一表项计算对应的灰度值 bGrayMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed + 0.587 * lpbmi->bmiColors[i].rgbGreen + 0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5); // 建立灰度调色板 //红色分量 lpbmi->bmiColors[i].rgbRed = i; // 绿色分量 lpbmi->bmiColors[i].rgbGreen = i; // 蓝色分量 lpbmi->bmiColors[i].rgbBlue = i; // 保留位 lpbmi->bmiColors[i].rgbReserved = 0; } else { //对原256色调色板的每一表项计算对应的灰度值 bGrayMap[i] = (BYTE)(0.299 * lpbmc->bmciColors[i].rgbtRed + 0.587 * lpbmc->bmciColors[i].rgbtGreen + 0.114 * lpbmc->bmciColors[i].rgbtBlue + 0.5); //建立灰度调色板 // 红色分量 lpbmc->bmciColors[i].rgbtRed = i; // 绿色分量 lpbmc->bmciColors[i].rgbtGreen = i; // 蓝色分量 lpbmc->bmciColors[i].rgbtBlue = i; } } // 找到DIB图像象素起始位置 lpDIBBits = ::FindDIBBits(lpDIB); // 获取图像宽度 lWidth = ::DIBWidth(lpDIB); // 获取图像高度 lHeight = ::DIBHeight(lpDIB); // 计算图像每行的字节数 OneLineBytes = WIDTHBYTES(lWidth * 8); // 更换原256色位图的每个象素的颜色索引 // 每行 for(ih = 0; ih < lHeight; ih++) { // 每列 for(iw= 0; iw < lWidth; iw++) { // 指向DIB第ih行,第iw列的象素的指针 lpSrc = (BYTE*)lpDIBBits + OneLineBytes * (lHeight - 1 - ih) +iw; //对256色位图,其像素值是调色板索引值 //对灰度图,索引值就等于其灰度值 //映射调色板索引 *lpSrc = bGrayMap[*lpSrc]; } } // 替换当前调色板为灰度调色板 pDoc->GetDocPalette()->SetPaletteEntries(0,256, (LPPALETTEENTRY)lpbmi->bmiColors); // 设置脏标记 pDoc->SetModifiedFlag(TRUE); // 实现新的调色板 OnDoRealize((WPARAM)m_hWnd,0); // 更新视图 pDoc->UpdateAllViews(NULL); // 解除锁定 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); // 恢复光标 EndWaitCursor(); } 5. 随机噪声 void CCimageProcessingView::OnRestoreRandomnoise() { // TODO: Add your command handler code here // 获取文档指针 CCimageProcessingDoc* pDoc = GetDocument(); // 指向DIB的指针 LPSTR lpDIB; // 获取DIB图像并锁定 lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); // 更改光标形状 BeginWaitCursor(); // 调用RandomNoise函数对DIB进行加噪处理 if (::RandomNoise(lpDIB)) { // 设置脏标记 pDoc->SetModifiedFlag(TRUE); // 更新视图 pDoc->UpdateAllViews(NULL); } else { // 提示用户 MessageBox("分配内存失败!"); } // 解除锁定 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); // 恢复光标 EndWaitCursor(); } /************************************************************************* * * 函数名称: * * RandomNoise() * * 参数: * * LPSTR lpDIB // 指向源DIB图像指针 * * 返回值: * * BOOL // 加入随机噪声操作成功返回TRUE,否则返回FALSE。 * * 说明: * * 该函数用来对256色位图和24位真彩色位图进行加入随即噪声操作。 * ************************************************************************/ BOOL WINAPI RandomNoise (LPSTR lpDIB) { // 图像宽度和高度 LONG lWidth,lHeight; // 指向图像像素的指针 LPSTR lpDIBBits; // 指向源图像的指针 LPSTR lpSrc; //循环变量 long i; long j; // 图像每行的字节数 LONG lLineBytes; //指向图像信息头结构的指针 LPBITMAPINFOHEADER lpbmi; //图像的颜色数 WORD wNumColors; //噪声 BYTE NoiseValue; // 计算图像每行的字节数 lpbmi=(LPBITMAPINFOHEADER)lpDIB; //计算图像的高度和宽度 lWidth=::DIBWidth(lpDIB); lHeight=::DIBHeight(lpDIB); //找到图像像素的起始位置 lpDIBBits=::FindDIBBits(lpDIB); //计算图像的颜色数 wNumColors=::DIBNumColors(lpDIB); //计算图像每行的字节数 lLineBytes = WIDTHBYTES(lWidth * lpbmi->biBitCount); //生成伪随机种子 srand((unsigned)time(NULL)); //在图像中加噪 //如果是256色位图 if(wNumColors==256) { for (j = 0;j < lHeight ;j++) { for(i = 0;i < lWidth ;i++) { //随机的噪声值 NoiseValue=rand()/1024; // 指向源图像倒数第j行,第i个象素的指针 lpSrc = (char *)lpDIBBits + lLineBytes * j + i; //在像素值中加入噪声值 *lpSrc = (BYTE)(((BYTE)*(lpSrc))*224/256 + NoiseValue); } } } //如果是24位真彩色位图 else if(wNumColors==0) { for (j = 0;j < lHeight ;j++) { for(i = 0;i < lWidth ;i++) { NoiseValue=rand()/1024; // 指向源图像倒数第j行,第i个象素的指针 lpSrc = (char *)lpDIBBits + lLineBytes * j + 3*i; //在每个像素的RGB分量中加入随机的噪声值 *lpSrc++ = (BYTE)(((BYTE)*(lpSrc++))*224/256 + NoiseValue); *lpSrc++ = (BYTE)(((BYTE)*(lpSrc++))*224/256 + NoiseValue); *lpSrc++ = (BYTE)(((BYTE)*(lpSrc++))*224/256 + NoiseValue); } } } //如果既不是256色位图也不是24 位真彩色位图,直接返回 else { AfxMessageBox("只支持256色位图和24位真彩色位图"); return false; } // 返回 return true; } 6.亮度调节 void CCimageProcessingView::OnEXPBright() { // TODO: Add your command handler code here CCimageProcessingDoc* pDoc=GetDocument(); LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB()); AdjustBrightness(lpDIB,-80); pDoc->SetModifiedFlag(true); OnDoRealize((WPARAM)m_hWnd,0); pDoc->UpdateAllViews(NULL); } /************************************************************************* * * 函数名称: * * AdjustBrightness () * * 参数: * * LPSTR lpDIB // 指向源DIB图像指针 * * int db * * BOOL //操作成功返回TRUE,否则返回FALSE。 * * 说明: * * 该算法函数用来对256色位图和24位真彩色位图进行亮度调整操作。 * ************************************************************************/ BOOL WINAPI AdjustBrightness(LPSTR lpDIB, int db) { BYTE r, g, b; BITMAPINFO *pbmi; WORD wNumColors; LONG i; LPSTR lpDIBBits; int nDelta; int iWidth, iHeight; if (lpDIB == NULL) return FALSE; pbmi = (BITMAPINFO *)lpDIB; if (! pbmi) return FALSE; wNumColors =::DIBNumColors(lpDIB); if (wNumColors==256) { for (i=0; ibmiColors[i].rgbRed = BOUND(pbmi->bmiColors[i].rgbRed+db, 0, 255); pbmi->bmiColors[i].rgbGreen = BOUND(pbmi->bmiColors[i].rgbGreen+db, 0, 255); pbmi->bmiColors[i].rgbBlue = BOUND(pbmi->bmiColors[i].rgbBlue+db, 0, 255); } } else if(wNumColors==0) { lpDIBBits= ::FindDIBBits(lpDIB); nDelta = WIDTHBYTES((pbmi->bmiHeader.biBitCount)*(pbmi->bmiHeader.biWidth)) - ((pbmi->bmiHeader.biWidth)*(pbmi->bmiHeader.biBitCount)+7)/8; for (iHeight=0; iHeightbmiHeader.biHeight; iHeight++) { for (iWidth=0; iWidthbmiHeader.biWidth; iWidth++) { b = (BYTE)*(lpDIBBits); g = (BYTE)*(lpDIBBits+1); r = (BYTE)*(lpDIBBits+2); *lpDIBBits++= BOUND(b+db, 0, 255); *lpDIBBits++= BOUND(g+db, 0, 255); *lpDIBBits++= BOUND(r+db, 0, 255); } lpDIBBits += nDelta; } } else { AfxMessageBox("只处理256色和24位位图"); return false; } return TRUE; } 7.色调调节 void CCimageProcessingView::OnExpColor() { // TODO: Add your command handler code here CCimageProcessingDoc* pDoc=GetDocument(); LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB()); AdjustColor(lpDIB,26,120,-30); pDoc->SetModifiedFlag(true); OnDoRealize((WPARAM)m_hWnd,0); pDoc->UpdateAllViews(NULL); } /************************************************************************* * * 函数名称: * * AdjustColor () * * 参数: * * LPSTR lpDIB // 指向源DIB图像指针 * * int dr dg db * * BOOL //操作成功返回TRUE,否则返回FALSE。 * * 说明: * * 该算法函数用来对256色位图和24位真彩色位图进行色调调整操作。 * ************************************************************************/ BOOL WINAPI AdjustColor(LPSTR lpDIB, int dr, int dg, int db) { BYTE r, g, b; BITMAPINFO *pbmi; WORD wNumColors; LONG i; LPSTR lpDIBBits; int nDelta; int iWidth, iHeight; if (lpDIB == NULL) return FALSE; pbmi = (BITMAPINFO *)lpDIB; if (! pbmi) return FALSE; wNumColors =::DIBNumColors(lpDIB); if (wNumColors==256) { for (i=0; ibmiColors[i].rgbRed = BOUND(pbmi->bmiColors[i].rgbRed+dr, 0, 255); pbmi->bmiColors[i].rgbGreen = BOUND(pbmi->bmiColors[i].rgbGreen+dg, 0, 255); pbmi->bmiColors[i].rgbBlue = BOUND(pbmi->bmiColors[i].rgbBlue+db, 0, 255); } } else if(wNumColors==0) { lpDIBBits= ::FindDIBBits(lpDIB); nDelta = WIDTHBYTES((pbmi->bmiHeader.biBitCount)*(pbmi->bmiHeader.biWidth)) - ((pbmi->bmiHeader.biWidth)*(pbmi->bmiHeader.biBitCount)+7)/8; for (iHeight=0; iHeightbmiHeader.biHeight; iHeight++) { for (iWidth=0; iWidthbmiHeader.biWidth; iWidth++) { b = (BYTE)*(lpDIBBits); g = (BYTE)*(lpDIBBits+1); r = (BYTE)*(lpDIBBits+2); *lpDIBBits++= BOUND(b+db, 0, 255); *lpDIBBits++= BOUND(g+dg, 0, 255); *lpDIBBits++= BOUND(r+dr, 0, 255); } lpDIBBits += nDelta; } } else { AfxMessageBox("只处理256色和24位位图"); return false; } return TRUE; } 8.对比度调节 void CCimageProcessingView::OnExpComp() { // TODO: Add your command handler code here CCimageProcessingDoc* pDoc=GetDocument(); LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB()); AdjustCotrast(lpDIB,80); pDoc->SetModifiedFlag(true); OnDoRealize((WPARAM)m_hWnd,0); pDoc->UpdateAllViews(NULL); } /************************************************************************* * * 函数名称: * * AdjustCotrast () * * 参数: * * LPSTR lpDIB // 指向源DIB图像指针 * * int dc * * BOOL //操作成功返回TRUE,否则返回FALSE。 * * 说明: * * 该算法函数用来对256色位图和24位真彩色位图进行对比度调整操作。 * ************************************************************************/ BOOL WINAPI AdjustCotrast(LPSTR lpDIB, int dc) { BYTE r, g, b; BITMAPINFO *pbmi; WORD wNumColors; LONG i; LPSTR lpDIBBits; int nDelta; int iWidth, iHeight; if (lpDIB == NULL) return FALSE; pbmi = (BITMAPINFO *)lpDIB; if (! pbmi) return FALSE; wNumColors =::DIBNumColors(lpDIB); if (wNumColors==256) { for (i=0; i=0) { int vMin=dc; int vMax=255-dc; float Grad=((float)(vMax-vMin))/255; IncreaseContrast(&(pbmi->bmiColors[i].rgbRed),vMin,vMax,Grad); IncreaseContrast(&(pbmi->bmiColors[i].rgbGreen),vMin,vMax,Grad); IncreaseContrast(&(pbmi->bmiColors[i].rgbBlue),vMin,vMax,Grad); } else { float Grad=255/(255+2*(float)dc); DecreaseContrast(&(pbmi->bmiColors[i].rgbRed),dc,Grad); DecreaseContrast(&(pbmi->bmiColors[i].rgbGreen),dc,Grad); DecreaseContrast(&(pbmi->bmiColors[i].rgbBlue),dc,Grad); } } } else if(wNumColors==0) { lpDIBBits= ::FindDIBBits(lpDIB); nDelta = WIDTHBYTES((pbmi->bmiHeader.biBitCount)*(pbmi->bmiHeader.biWidth)) - ((pbmi->bmiHeader.biWidth)*(pbmi->bmiHeader.biBitCount)+7)/8; for (iHeight=0; iHeightbmiHeader.biHeight; iHeight++) { for (iWidth=0; iWidthbmiHeader.biWidth; iWidth++) { b = (BYTE)*(lpDIBBits); g = (BYTE)*(lpDIBBits+1); r = (BYTE)*(lpDIBBits+2); if(dc>=0) { int vMin=dc; int vMax=255-dc; float Grad=((float)(vMax-vMin))/255; IncreaseContrast(&b,vMin,vMax,Grad); IncreaseContrast(&g,vMin,vMax,Grad); IncreaseContrast(&r,vMin,vMax,Grad); } else { float Grad=255/(255+2*(float)dc); DecreaseContrast(&b,dc,Grad); DecreaseContrast(&g,dc,Grad); DecreaseContrast(&r,dc,Grad); } *lpDIBBits++= b; *lpDIBBits++= g; *lpDIBBits++= r; } lpDIBBits += nDelta; } } else { AfxMessageBox("只处理256色和24位位图"); return false; } return TRUE; }

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档