MFC单文档图像处理代码--句柄图像实现

来源:互联网 发布:怎么看iphone的mac地址 编辑:程序博客网 时间:2024/06/05 11:25

1.句柄图像灰度化+二值化

void Convert256toGray(HDIB hDIB,int a,int b,int c,int d){LPSTRlpDIB;// 由DIB句柄得到DIB指针并锁定DIBlpDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);// 指向DIB象素数据区的指针LPSTR   lpDIBBits;// 指向DIB象素的指针BYTE *lpSrc;// 图像宽度LONGlWidth;// 图像高度LONG  lHeight;// 图像每行的字节数LONGlLineBytes;// 指向BITMAPINFO结构的指针(Win3.0)LPBITMAPINFO lpbmi;// 指向BITMAPCOREINFO结构的指针LPBITMAPCOREINFO lpbmc;// 获取指向BITMAPINFO结构的指针(Win3.0)lpbmi = (LPBITMAPINFO)lpDIB;// 获取指向BITMAPCOREINFO结构的指针lpbmc = (LPBITMAPCOREINFO)lpDIB;// 灰度映射表BYTE bMap[256];// 计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板inti,j;for (i = a; i < 256; i ++){// 计算该颜色对应的灰度值bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed +0.587 * lpbmi->bmiColors[i].rgbGreen +0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5);// 更新DIB调色板红色分量lpbmi->bmiColors[i].rgbRed = i;// 更新DIB调色板绿色分量lpbmi->bmiColors[i].rgbGreen = i;// 更新DIB调色板蓝色分量lpbmi->bmiColors[i].rgbBlue = i;// 更新DIB调色板保留位lpbmi->bmiColors[i].rgbReserved = 0;}// 找到DIB图像象素起始位置lpDIBBits = ::FindDIBBits(lpDIB);// 获取图像宽度lWidth = ::DIBWidth(lpDIB);// 获取图像高度lHeight = ::DIBHeight(lpDIB);// 计算图像每行的字节数lLineBytes = WIDTHBYTES(lWidth * 8);// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)//逐行扫描for(i = 0; i < lWidth; i++){//逐列扫描for(j = 0; j < lHight; j++){// 指向DIB第i行,第j个象素的指针lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;// 变换*lpSrc = bMap[*lpSrc];}//最简单二值化:找灰度值,大于127的全部变成255,小于127的全部变成0for(i=0;i<lWidth;i++){for (j=0;j<lHight;j++){if (bMap[i]<127){bMap[i]=0;}else{bMap[i]=255;}}*lpSrc = bMap[*lpSrc];}}//解除锁定::GlobalUnlock ((HGLOBAL)hDIB);}
2.句柄图像旋转

#define PI 3.14159#define RADIAN(angle) ((angle)*PI/180.0) HGLOBAL WINAPI RotateDIB(LPSTR lpDIB, int iRotateAngle){LONGlWidth;LONGlHeight;LONGlNewWidth;LONGlNewHeight;LONGlLineBytes;LONGlNewLineBytes;LPSTRlpDIBBits;LPSTRlpSrc;HDIBhDIB;LPSTRlpDst;LPSTRlpNewDIB;LPSTRlpNewDIBBits;LPBITMAPINFOHEADER lpbmi;LPBITMAPCOREHEADER lpbmc;LONGi;LONGj;LONGi0;LONGj0;floatfRotateAngle;floatfSina, fCosa;floatfSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4;floatfDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4;floatf1,f2;lpDIBBits = ::FindDIBBits(lpDIB);lWidth = ::DIBWidth(lpDIB);lLineBytes = WIDTHBYTES(lWidth * 8);lHeight = ::DIBHeight(lpDIB);fRotateAngle = (float) RADIAN(iRotateAngle);fSina = (float) sin((double)fRotateAngle);fCosa = (float) cos((double)fRotateAngle);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 =  fCosa * fSrcX1 + fSina * fSrcY1;fDstY1 = -fSina * fSrcX1 + fCosa * fSrcY1;fDstX2 =  fCosa * fSrcX2 + fSina * fSrcY2;fDstY2 = -fSina * fSrcX2 + fCosa * fSrcY2;fDstX3 =  fCosa * fSrcX3 + fSina * fSrcY3;fDstY3 = -fSina * fSrcX3 + fCosa * fSrcY3;fDstX4 =  fCosa * fSrcX4 + fSina * fSrcY4;fDstY4 = -fSina * fSrcX4 + fCosa * fSrcY4;lNewWidth  = (LONG) ( max( fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2) ) + 0.5);lNewLineBytes = WIDTHBYTES(lNewWidth * 8);lNewHeight = (LONG) ( max( fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2) )  + 0.5);f1 = (float) (-0.5 * (lNewWidth - 1) * fCosa - 0.5 * (lNewHeight - 1) * fSina+ 0.5 * (lWidth  - 1));f2 = (float) ( 0.5 * (lNewWidth - 1) * fSina - 0.5 * (lNewHeight - 1) * fCosa+ 0.5 * (lHeight - 1));hDIB = (HDIB) ::GlobalAlloc(GHND, lNewLineBytes * lNewHeight + *(LPDWORD)lpDIB + ::PaletteSize(lpDIB));if (hDIB == NULL){return NULL;}lpNewDIB =  (char * )::GlobalLock((HGLOBAL) hDIB);memcpy(lpNewDIB, lpDIB, *(LPDWORD)lpDIB + ::PaletteSize(lpDIB));lpNewDIBBits = ::FindDIBBits(lpNewDIB);lpbmi = (LPBITMAPINFOHEADER)lpNewDIB;lpbmc = (LPBITMAPCOREHEADER)lpNewDIB;if (IS_WIN30_DIB(lpNewDIB)){lpbmi->biWidth = lNewWidth;lpbmi->biHeight = lNewHeight;}else{lpbmc->bcWidth = (unsigned short) lNewWidth;lpbmc->bcHeight = (unsigned short) lNewHeight;}for(i = 0; i < lNewHeight; i++){for(j = 0; j < lNewWidth; j++){lpDst = (char *)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + j;i0 = (LONG) (-((float) j) * fSina + ((float) i) * fCosa + f2 + 0.5);j0 = (LONG) ( ((float) j) * fCosa + ((float) i) * fSina + f1 + 0.5);if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight)){lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0;*lpDst = *lpSrc;}else{* ((unsigned char*)lpDst) = 255;}}}return hDIB;}
3.ROI区域实现

////////roi区域void CMyDIPView::OnLButtonDown(UINT nFlags, CPoint point){TopX = point.x;TopY = point.y;flag_LMoseDown = true;LeftTopPoint = point;RightBottomPoint = point;//设置光标::SetCursor(Cross);// TODO: 在此添加消息处理程序代码和/或调用默认值CScrollView::OnLButtonDown(nFlags, point);}void CMyDIPView::OnMouseMove(UINT nFlags, CPoint point){if(flag_LMoseDown){CClientDC dc(this);dc.SetROP2(R2_NOT);dc.SelectStockObject(NULL_BRUSH);::SetCursor(Cross);RightBottomPoint = point;}// TODO: 在此添加消息处理程序代码和/或调用默认值CScrollView::OnMouseMove(nFlags, point);}void CMyDIPView::OnLButtonUp(UINT nFlags, CPoint point){//记录松开点的坐标信息BottomX = point.x;BottomY = point.y;width = BottomX-TopX;height = BottomY-TopY;//判断所选区域是否合格if(height < 0||width < 0){MessageBox(TEXT("请从左上角开始选取"));return ;}if(height > width){MessageBox(TEXT("请选取一个横向矩形"));return ;}flag_LMoseDown = false;CClientDC dc(this);dc.SetROP2(R2_NOT);dc.SelectStockObject(NULL_BRUSH);::ClipCursor(NULL);RightBottomPoint = point;//画出所选矩形区域dc.Rectangle(CRect(LeftTopPoint,RightBottomPoint));//创建CRect类的对象保存ROI区域长宽,起始终止点的信息ret = new CRect(LeftTopPoint,RightBottomPoint);flagBinROI = true;CScrollView::OnLButtonUp(nFlags, point);}
看不懂的,查资料!加油


原创粉丝点击