你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 图形图象处理与游戏编程
双线性插值的图像缩放算法(下)
 

2.核心代码

//函数名Bilinear

//参数float k

//返回值无

//作用利用双线性插值来实现图像缩放

void CChildView::Bilinear(float k)

{  

    int nBpp=m_imPicture .GetBPP ();   

    int widthNew,heightNew;//新图像的宽度和高度

    float widthScale=(float)(1.0/k),heightScale=(float)(1.0/k);

    float xx,yy;

    int a,b;

    int rr,gg,bb;//保存RGB分量

    //得到新图像的宽度和高度

    widthNew=(int)(m_imPicture .GetWidth ()*k);

    heightNew =(int)(m_imPicture .GetHeight ()*k);

    //利用新图像的宽度和高度来创建新图像

    m_imNewPicture .Destroy ();

    m_imNewPicture .Create (widthNew ,heightNew ,nBpp);

    //得到新、老图像的每行的字节数

    int nPitch=m_imPicture .GetPitch ();

    int nPitchNew=m_imNewPicture .GetPitch ();

    //得到新、老图像的数据指针

    LPBYTE pBitsNew=(LPBYTE)m_imNewPicture .GetBits ();

    LPBYTE pBits=(LPBYTE)m_imPicture .GetBits ();  

    if(m_imPicture.GetBPP ()!=24){

        MessageBox ("必须是24位图像或8位图像");

        m_imNewPicture .Destroy ();

        Invalidate();

        return ;

    }  

    for(int x=(int)k;x<widthNew -k;x++){

        for(int y=(int)k;y<heightNew -k;y++){

            xx=x*widthScale ;

            yy=y*heightScale ;

            if(xx<=1e-8){

                xx=0;

            }

            if(xx>m_imPicture .GetWidth ()-2)

                xx=(float)(m_imPicture .GetWidth ()-2);

            if(yy<=1e-8)

                yy=0;

            if(yy>m_imPicture .GetHeight ()-2)

                yy=(float)(m_imPicture .GetHeight ()-2);

            a=(int)xx;

            b=(int)yy;         

            //分别得到对应像素的RGB值并用双线性插值得到新像素的RGB

            int r11,r12,r21,r22;

            r11=*(pBits+b*nPitch+3*a+2);

            r12=*(pBits+b*nPitch+3*(a+1)+2);

            r21=*(pBits+(b+1)*nPitch+3*a+2);

            r22=*(pBits+(b+1)*nPitch+3*(a+1)+2);

            rr=(int)(r11*(a+1-xx)*(b+1-yy)+r12*(a+1-xx)*(yy-b)

                +r21*(xx-a)*(b+1-yy)+r22*(xx-a)*(yy-b));

 

            int g11,g12,g21,g22;

            g11=*(pBits+b*nPitch+3*a+1);

            g12=*(pBits+b*nPitch+3*(a+1)+1);

            g21=*(pBits+(b+1)*nPitch+3*a+1);

            g22=*(pBits+(b+1)*nPitch+3*(a+1)+1);

            gg=(int)(g11*(a+1-xx)*(b+1-yy)+g12*(a+1-xx)*(yy-b)

                +g21*(xx-a)*(b+1-yy)+g22*(xx-a)*(yy-b));

 

            int b11,b12,b21,b22;

            b11=*(pBits+b*nPitch+3*a);

            b12=*(pBits+b*nPitch+3*(a+1));

            b21=*(pBits+(b+1)*nPitch+3*a);

            b22=*(pBits+(b+1)*nPitch+3*(a+1));

            bb=(int)(b11*(a+1-xx)*(b+1-yy)+b12*(a+1-xx)*(yy-b)

                +b21*(xx-a)*(b+1-yy)+b22*(xx-a)*(yy-b));

            //将得到的新RGB值写到新图像中          

            *(pBitsNew +y*nPitchNew +x*3)=min(255,bb);

            *(pBitsNew +y*nPitchNew +x*3+1)=min(255,gg);

            *(pBitsNew +y*nPitchNew +x*3+2)=min(255,rr);

        }      

    }      

    m_imPicture .Destroy ();

    Invalidate ();

}

五.结语

   本文介绍了一种利用双线性插值来实现图像缩放的算法,通过图2左图是利用本文介绍的双线性插值算法缩小一倍得到图像,右图是利用StretchBlt缩小一倍得到图像可以看到这种算法和传统的利用StretchBlt来实现图像缩放相比具有很大的改善。StretchBlt实现的图像具有很大的失真,并且随着缩小的比率越大失真也越严重;而双线性插值算法则很好的解决了这个问题,可以得到很高的清晰度,这种方法可以广泛应用在图像变形、计算机动画、计算机辅助设计等领域。所附源代码在VC++.NET 2003下编译通过。


2

 

参考文献

 

1]求是科技. Visual C++数字图像处理典型算法及实现. 人民邮电出版社,2006.

2K.R.Castleman. 数字图像处理. 电子工业出版社,2002.

3Donald Hearn等计算机图形学. 电子工业出版社,2007.

4Kruglinski D.J. Visual C++技术内幕,清华大学出版社.
  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089