使用CImage显示透明的PNG图片

      CImage的AlphaBlend函数可以显示半透明或透明的图片,但是当使用这个函数显示PNG图片时,经常会发现PNG图片的背景没有透明,而是被显示为白色.在网上多处搜索都没有找到原因,只能自己动手了.通过调试代码可以发现,CImage的AlphaBlend函数内部调用的是全局的Window API函数:
 
       CImage类在调用这个函数时,将自己的内部DC传递给hdcSrc,将目标DC传递给hdcDest.MSDN详细描述这个函数的最后一个参数BLENDFUNCTION blendFunction. BLENDFUNCTION定义如下:

     
      BlendOp总是为AC_SRC_OVER;BlendFlags为保留项,必须为0;SourceConstantAlpha是图片整体的不透明度,如果要使用图片像素自身的Alpha值,则要将这个参数设置为255;最后一个参数,如果使用SourceConstantAlpha作为描画图片的整体不透明度,则为设置为0,如果使用图片像素自身的Alpha值,则设置为AC_SRC_ALPHA.我们在描画带有透明效果的PNG图片时,要使用图片像素自身的Alpha值,所以要将SourceConstantAlpha设置为255,将AlphaFormat设置为AC_SRC_ALPHA.MSDN对这种情况下颜色混合的计算方法作了描述,如下:

      Src是指我们要描画的图片,Dst是指目标DC的上下文,Src.Alpha应该不是像素的Alpha值,而应该是Alpha/255;按照这个公式,我们可以举个例子计算一下:Src上一个像素为RGB(255, 255, 255),Alpha值为0,与之混合的Dst上相应像素为RGB(128, 128, 128),混合后得出的结果为:
R = 255 + (1 - 0 / 255) * 128;
G = 255 + (1 - 0 / 255) * 128;
B = 255 + (1 - 0 / 255) * 128;
计算结果大于255,函数内部自动将其设置为255,最后为RGB(255, 255, 255),仍然为白色.而当Src中像素的颜色为RGB(0, 0, 0),则结果为Dst的颜色RGB(128, 128, 128),实现了透明效果.按照这个公式计算,很多颜色的半透明或透明效果都无法实现.
参考MSDN上在SourceConstantAlpha不等于255时的混合计算公式,我们可以将公式修改为

  

按照这个公式计算,我们上面例子的结果为RGB(128, 128, 128),可以实现透明效果.
    根据以上分析,我们只用修改CImage中像素的颜色,就可以实现透明与半透明的效果了,代码如下:

void CSample::Draw(CDC* pDC, int iX, int iY)
{
//m_stImage为CImage的对象
    for(int i = 0; i < m_stImage.GetWidth(); ++i)
    {
        for(int j = 0; j < m_stImage.GetHeight(); ++j
        {
            unsigned char* pucColor = m_stImage.GetPixelAddress(i , j);
            pucColor[0] = pucColor[0] * pucColor[3] / 255;
            pucColor[1] = pucColor[1] * pucColor[3] / 255;
            pucColor[2] = pucColor[2] * pucColor[3] / 255;
        }
     }
    m_stImage.AlphaBlend(pDC->m_hDC, iX, iY);      
}


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wormsun/archive/2008/11/13/3293741.aspx

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值