好久都没有写博客了,因为开发进入到白热化阶段,就发现没有多少时间可以用来写博客了。。

不过还是要把这个小技术点记录一下,因为困扰了我好久,终于在codeguru上找到了解决办法。

在MFC中,在使用CImage类(vs2008及以上)的时候,读取PNG图片并显示,实际上并不是透明的,这里是微软的一个BUG,他对透明的处理就是“白色”。先来做一个实验,为了让结果比较明显,把对话框的背景设为一个便于区别的颜色。

建立一个新的对话框工程,背景色设为RGB(255, 202, 138)。估计还有很多人不知道肿么设置对话框的背景色,很简单,在OnInitDialog()中添加这句代码即可:

  1. this->SetBackgroundColor(RGB(255,202,138));

测试的方法就是点击鼠标后画上一个小PNG图片。添加鼠标抬起事件:

  1. //CpngTestDlg.h
  2. CImage m_pngImage;
  3. //CpngTestDlg.cpp
  4. BOOL CpngTestDlg::OnInitDialog()
  5. {
  6. ...
  7. m_pngImage.Load(_T("c:\\flag.png"));
  8. }
  9. void CpngTestDlg::OnLButtonUp(UINT nFlags, CPoint point)
  10. {
  11. // TODO: Add your message handler code here and/or call default
  12. CDC * pDC = GetDC();
  13. m_pngImage.Draw(pDC->GetSafeHdc(), point.x, point.y);
  14. CDialogEx::OnLButtonUp(nFlags, point);
  15. }

好了,运行,在对话框里随便点一下,可以看到,效果并不是我们想要的。

当时遇见这个问题,第一个想的是,是不是图片的问题?后来在PS中查看了一下,排除了Alpha通道的问题。会不会是CImage类的问题?是不是需要对透明图片进行额外的设置?带着这几个问题,去网上找了些资料。很多解决方案都是使用TransparentBlt(),设定关键色为白色,来绘制图片。我试了一下,没有效果,不知道他们是如何成功的。

最终在codeguru上找到了解决方案,现在那个帖子已经不在了,不知道为什么。。

先来看看造成这种现象的原因是什么:

      PNG图片的透明背景总是一片白色,后来才发现这其实是微软GDI+的设计问题, PNG图片是ARGB,使用GDI+载入图片的时候,GDI+会默认已经进行了预剩运算(PARGB), 即每象素的实际值是已经和ALPHA值按比例相乘的结果,实际上它根本就没有做预乘, 在使用透明图片的象素ALPHA通道的时候,CImage内部正是调用的AlphaBlend, 没有预乘的图当作预乘的图片处理的结果就是这相当于一张和纯白背景进行了预剩, 所以图象总是出现白色背景。

然后对症下药,在载入图像之后,对其进行处理:

  1. for(int i = 0; i < m_pngImage.GetWidth(); i++)
  2. {
  3. for(int j = 0; j < m_pngImage.GetHeight(); j++)
  4. {
  5. unsigned char* pucColor = reinterpret_cast<unsigned char *>(m_pngImage.GetPixelAddress(i , j));
  6. pucColor[0] = pucColor[0] * pucColor[3] / 255;
  7. pucColor[1] = pucColor[1] * pucColor[3] / 255;
  8. pucColor[2] = pucColor[2] * pucColor[3] / 255;
  9. }
  10. }

然后再看看结果:

转载于:https://blog.51cto.com/serious/933250

真正“透明”的PNG图片相关推荐

  1. IE6下PNG图片透明效果(PNG图片做背景也可以)

    懒人萱在这里保证发的文章都是高质量的经过测试的JS代码,而且IE6.IE7和火狐都兼容的,希望大家多多关注我的帖子,我会把我的经验都共享出来哦! 懒人萱在寻找PNG图片透明效果的JS特效代码的时候,发 ...

  2. java 显示透明背景png图片

    首先理由ps生成一个背景透明的png图片,然后设置JPanel面板的透明属性,也就是panel.setOpaque(false);设置为透明 class MyPanel extends JLayere ...

  3. 为什么存png还有白色底_用photoshop保存透明背景的图片为png格式,为什么打开后是白色背景了?...

    Photoshop想要保存透2113明背景的图片要保存PNG格式,保存JPG格式就5261会变成图片.41021.电脑打开Photoshop.2.打1653开Photoshop后,打开一张图片.3.打 ...

  4. 透明Png黑白图片上色(重新着色、改变成指定颜色)

    场景:有时,我们需要给透明Png黑白图片改变成指定颜色(上色). 前提:我们已经做好了带透明通道的PNG图片. 益处:使用此方法,只需要制作一张透明的黑色PNG图片即可,我们需要不同颜色的同样式图片时 ...

  5. Python 基于透明元素裁切图片(类似Photoshop)

    文章目录 问题描述 解决方案 参考文献 本文测试图像及其代码下载 问题描述 实现类似Photoshop的基于透明元素裁切图片 1.png 2.jpg 3.png 4.png 5.png 6.png 解 ...

  6. cocos creator 设置开启canvas 透明后 半透明图片 不正常的 官方解决办法

    cocos creator 设置开启canvas 透明后 半透明图片 不正常的 官方解决办法 必须用 one,one minus src alpha,否则 web 端的贴图渲染时会莫名其妙和 canv ...

  7. Graphics2D 在一张图片上添加一个带有透明背景的图片或绘制透明图片

    目录 代码实例 代码实例 // 读取原图片信息 底图//得到文件File file = new File("d:\\1.png");//文件转化为图片Image srcImg = ...

  8. 用Ps将PSD切片并将切片保存为透明背景的图片

    第一步:选择放大镜工具或者Ctrl++将要切片的部分放大. 第二步:选择移动工具单击要切片的部分,在右边的图层栏找到要切片的图层在文字上右键选择转换为智能对象,再右键该图层的文字选择栅格化图层. 第三 ...

  9. VB.NET:生成底色透明的PNG图片

    2019独角兽企业重金招聘Python工程师标准>>> 今天研究了下.NET窗体应用程序生成透明底色的PNG图像. 我的.NET版本为.NET 4.5,VS版本为VS2012,操作系 ...

  10. Java 创建背景透明的文字图片、将文本写到图片上

    Java 创建背景透明的文字图片.将文本写到图片上: import sun.font.FontDesignMetrics;import javax.imageio.ImageIO; import ja ...

最新文章

  1. 常见数据库的Connection URL
  2. 如何测试一个电梯,测试方案及测试用例
  3. python信息找人的算法_算法篇-python查找算法
  4. jgit_JGit身份验证说明
  5. 2018.08.29 NOIP模拟 pmatrix(线性筛)
  6. 定义快捷代码_nodepad++代码编辑器替代工具整理
  7. python与excel-Python 与 Excel 不得不说的事
  8. VirtualBox安装debian无法启动,正确的解决办法
  9. 给ftp服务器创建文件夹,ftp服务器创建文件夹
  10. 网络控制播放器(局域网内通过TCP和UDP控制视频播放器)
  11. 华三模拟器BGP基本配置
  12. BaseRecyclerViewAdapterHelper源码解读(四) 上拉加载更多
  13. 【控制篇 / 应用】(6.0) ❀ 01. 只允许使用 QQ 和微信 (上) ❀ FortiGate 防火墙
  14. 关于python的环境配置和编辑器Geany的使用中遇见的问题及解决方法
  15. Pyhton 裁剪视频尺寸 脚本
  16. 交通流量预测-混合注意力时空图卷积-ASTGCN
  17. mac无法调节屏幕亮度
  18. centos6.9安装Panoply
  19. 日常英文缩写以及杂记
  20. AUTOSAR-自旋锁(spinlock)与互斥锁

热门文章

  1. java求六位数以内所有自幂数
  2. ES6中新的AJAX解决方案:Promise、Fetch、Response、Axios
  3. keypair java_Java KeyPairGenerator genKeyPair()用法及代码示例
  4. photoshop中怎么绘制虚线
  5. 运放搭建的跟随电路作用与分析
  6. 天数转换成具体有多少年多少月多少天
  7. 类型数组HTML5 中的新数组
  8. centos7 设置外部访问
  9. 在Ubuntu-server下安装i3wm并简单配置
  10. 大侠周鸿祎——腾讯,你丫动手吧!