2012-03-17 10:23:40|?次阅读|上传:wustguangh【已有?条评论】发表评论
关键词:C/C++, 图形/图像|来源:唯设编程网
VC编程实现位图图像二值化、反相介绍了VC对位图图像二值化、反相处理,本文继续介绍位图处理类CImageUtility的其它成员方法,限于篇幅,本文着重介绍VC编程实现切除二值图的空白边、位图图像拷贝的两个成员方法。
//切除二值图的空白边 void CImageUtility::ImageCutBlankProcess(){ // 目前只处理24位以上的位图 if(nPixBytes <3) return; //有效区域 RECT vRect; vRect.top=0; vRect.left=0; vRect.right=bmSrcInfo.bmWidth; vRect.bottom=bmSrcInfo.bmHeight; //循环控制开关 bool bStop; double limenGray=255; // 1.求有效区域的Top值 bStop=false; for(long nHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++) { for(long nWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++) { //将RGB分量保存成为对应的灰度值 for(int np2=0; np2<nPixBytes; np2++) { //判断三个颜色分量是否为 if(pBmBits[bmSrcInfo.bmWidthBytes*nHeight+nWidth*nPixBytes + np2]<limenGray){ vRect.top=nHeight; bStop=true; break; } } if(bStop) break; } if(bStop) break; } // 2.求有效区域的Left值 bStop=false; for(long nWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++) { for(long nHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++) { //将RGB分量保存成为对应的灰度值 for(int np2=0; np2<nPixBytes; np2++) { //判断三个颜色分量是否为 if(pBmBits[bmSrcInfo.bmWidthBytes*nHeight+nWidth*nPixBytes + np2]<limenGray){ vRect.left=nWidth; bStop=true; break; } } if(bStop) break; } if(bStop) break; } // 3.求有效区域的Bottom值 bStop=false; for(long nHeight=bmSrcInfo.bmHeight-1; nHeight>=0; nHeight--) { for(long nWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++) { //将RGB分量保存成为对应的灰度值 for(int np2=0; np2<nPixBytes; np2++) { //判断三个颜色分量是否为 if(pBmBits[bmSrcInfo.bmWidthBytes*nHeight+nWidth*nPixBytes + np2]<limenGray){ vRect.bottom=nHeight+1; bStop=true; break; } } if(bStop) break; } if(bStop) break; } // 4.求有效区域的Right值 bStop=false; for(long nWidth=bmSrcInfo.bmWidth-1; nWidth>=0; nWidth--) { for(long nHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++) { //将RGB分量保存成为对应的灰度值 for(int np2=0; np2<nPixBytes; np2++) { //判断三个颜色分量是否为 if(pBmBits[bmSrcInfo.bmWidthBytes*nHeight+nWidth*nPixBytes + np2]<limenGray){ vRect.right=nWidth+1; bStop=true; break; } } if(bStop) break; } if(bStop) break; } //拷贝满足要求的位图区域 HBITMAP cutBitmap=CopyBitmap((HBITMAP)(*bmpSrc),&vRect); ::DeleteObject((HBITMAP)bmpSrc); this->loadHBitmap(cutBitmap); }
首先对二值图像进行行扫描,获取首行不是空白行的行号,末行不是空白行的行号,然后对二值图像进行列扫描,获取首列不是空白列的列号,末列不是空白列的列号,将获取的区域作为形参,调用位图拷贝函数:
HBITMAP cutBitmap=CopyBitmap((HBITMAP)(*bmpSrc),&vRect);
将指定区域内的像素信息拷贝出来形成一个新的二值图图像。
// 位图拷贝的实现 // pRect:定义拷贝位图区域的指针 HBITMAP CImageUtility::CopyBitmap(HBITMAP hSourcehBitmap,RECT* pRect) { // 定义设备描述表 CDC sourcedc; CDC destdc; sourcedc.CreateCompatibleDC(NULL); destdc.CreateCompatibleDC(NULL); //the bitmap information. BITMAP bm = {0}; //get the bitmap information. ::GetObject(hSourcehBitmap, sizeof(bm), &bm); // 根据用户是否定义了拷贝区域执行相应的操作 int imgWidth=bm.bmWidth; //图像的宽度 int imgHeight=bm.bmHeight; //图像的高度 int srcX=0; //源图像X起点 int srcY=0; //源图像Y起点 // 根据用户是否定义了拷贝区域执行相应的操作 if(pRect!=NULL){ imgWidth=bm.bmWidth<abs(pRect->right-pRect->left)?bm.bmWidth:abs(pRect->right-pRect->left); imgHeight=bm.bmHeight<abs(pRect->bottom-pRect->top)?bm.bmHeight:abs(pRect->bottom-pRect->top); srcX=pRect->left; srcY=pRect->top; } // create a bitmap to hold the result HBITMAP hbmresult = ::CreateCompatibleBitmap(CClientDC(NULL), imgWidth, imgHeight); HBITMAP hbmoldsource = (HBITMAP)::SelectObject(sourcedc.m_hDC, hSourcehBitmap); HBITMAP hbmolddest = (HBITMAP)::SelectObject(destdc.m_hDC, hbmresult); destdc.BitBlt(0,0,imgWidth, imgHeight, &sourcedc, srcX, srcY, SRCCOPY); // restore dcs ::SelectObject(sourcedc.m_hDC, hbmoldsource); ::SelectObject(destdc.m_hDC, hbmolddest); ::DeleteObject(sourcedc.m_hDC); ::DeleteObject(destdc.m_hDC); return hbmresult; }
到此,便完成了切除位图空白边,拷贝位图图像的成员函数