VC编程实现位图拷贝、切除空白边

2012-03-17 10:23:40|?次阅读|上传:wustguangh【已有?条评论】发表评论

关键词:C/C++, 图形/图像|来源:唯设编程网

VC编程实现位图图像二值化、反相介绍了VC对位图图像二值化、反相处理,本文继续介绍位图处理类CImageUtility的其它成员方法,限于篇幅,本文着重介绍VC编程实现切除二值图的空白边、位图图像拷贝的两个成员方法。

1. 切除二值图的空白边

//切除二值图的空白边
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);

将指定区域内的像素信息拷贝出来形成一个新的二值图图像。

2. 位图图像拷贝

// 位图拷贝的实现
// 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;
}

到此,便完成了切除位图空白边,拷贝位图图像的成员函数

发表评论0条 】
网友评论(共?条评论)..
VC编程实现位图拷贝、切除空白边