转载自:http://blog.csdn.net/zhongbin104/article/details/8730935

先看看GDI+的方法
方法1:

 

1.GDI+画透明图层(alpha)的png图片


stdafx加入如下:

 
  1. #include //初始化一下com口 #include "GdiPlus.h" using namespace Gdiplus; #pragma comment(lib,"gdiplus.lib")
 

开始初始化:
在app类的声明里(.h)加入:

 
  1. ULONG_PTR m_gdiplusToken;
 
 

InitInstance()里加入://若没有usingnamespace Gdiplus; 就要在前面加Gdiplus::

 
  1. GdiplusStartupInput gdiplusStartupInput;
  2. GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
 

重载ExitInstance,加入GdiplusShutdown(m_gdiplusToken);

 
  1. int CxxxApp::ExitInstance()
  2. { // TODO: 在此添加专用代码和/或调用基类 GdiplusShutdown(m_gdiplusToken); return CWinApp::ExitInstance();
  3. }
 

显示图片的过程如下

  1. CClientDC *pDC = new CClientDC(GetDlgItem(IDC_STATIC_PIC));
  2. CRect rect;
  3. GetDlgItem(IDC_STATIC_PIC)->GetWindowRect(&rect);
  4. Graphics graphics(pDC->m_hDC); // Create a GDI+ graphics object Image image(_T("1.png")); // Construct an image graphics.DrawImage(&image, 0, 0, image.GetWidth(), image.GetHeight()); delete pDC;

这是用GDI+来显示图片。

 

2.CImage绘制带alpha透明图层的png图片


用MFC自带的CImage也可以显示,不过要稍微进行转换才能得到正常的带α通道的png图片!

在画图前进行一次转换,其中Image是CImage的对象
  1. if (Image.GetBPP() == 32) //确认该图像包含Alpha通道 { int i; int j; for (i = 0; i < Image.GetWidth(); i++)
  2. { for (j = 0; j < Image.GetHeight(); j++)
  3. {
  4. byte *pByte = (byte *)Image.GetPixelAddress(i, j);
  5. pByte[0] = pByte[0] * pByte[3] / 255;
  6. pByte[1] = pByte[1] * pByte[3] / 255;
  7. pByte[2] = pByte[2] * pByte[3] / 255;
  8. }
  9. }
  10. }

具体方法如下:

 
  1. HWND hwnd = GetSafeHwnd(); //获取窗口的HWND ::InvalidateRect( hwnd, NULL, true ); //或者 ::InvalidateRect( hwnd, NULL, false ); ::UpdateWindow(hwnd); //若使用前不想把原来绘制的图片去掉,可以删去上面那三段 CDC *pDC = GetDC();
  2. CImage Image;
  3. Image.Load(strPath); if (Image.IsNull())
  4. {
  5. MessageBox(_T("没加载成功")); return -1;
  6. } if (Image.GetBPP() == 32) //确认该图像包含Alpha通道 { int i; int j; for (i = 0; i < Image.GetWidth(); i++)
  7. { for (j = 0; j < Image.GetHeight(); j++)
  8. {
  9. byte *pByte = (byte *)Image.GetPixelAddress(i, j);
  10. pByte[0] = pByte[0] * pByte[3] / 255;
  11. pByte[1] = pByte[1] * pByte[3] / 255;
  12. pByte[2] = pByte[2] * pByte[3] / 255;
  13. }
  14. }
  15. }
  16. Image.Draw(pDC->m_hDC, 0, 0);
  17. Image.Destroy();
  18. ReleaseDC(pDC);
代码中内部的框架是对图像的再次处理,对原来进行了修正,这样得到的更加正常,代码实测如下
绘图后效果
 

3.如果图片是在资源里的时候加载方法又不一样


这时需要两个函数,
对于GDI+如下:
 
  1. BOOL ImageFromIDResource(UINT nID, LPCTSTR sTR,Image *&pImg)
  2. {
  3. HINSTANCE hInst = AfxGetResourceHandle();
  4. HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type if (!hRsrc) return FALSE; // load resource into memory DWORD len = SizeofResource(hInst, hRsrc);
  5. BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc); if (!lpRsrc) return FALSE; // Allocate global memory on which to create stream HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
  6. BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
  7. memcpy(pmem,lpRsrc,len);
  8. GlobalUnlock(m_hMem);
  9. IStream* pstm;
  10. CreateStreamOnHGlobal(m_hMem,FALSE,&pstm); // load from stream pImg=Gdiplus::Image::FromStream(pstm); // free/release stuff pstm->Release();
  11. FreeResource(lpRsrc);
  12. GlobalFree(m_hMem); return TRUE;
  13. }
 
这时加载图片的代码变为:
  1. CClientDC *pDC = new CClientDC(GetDlgItem(IDC_STATIC_PIC));
  2. CRect rect;
  3. GetDlgItem(IDC_STATIC_PIC)->GetWindowRect(&rect);
  4. Graphics graphics(pDC->m_hDC); // Create a GDI+ graphics object Image *pimage; // Construct an image ImageFromIDResource(IDB_PNG1,_T("PNG"),pimage);
  5. graphics.DrawImage(pimage, 0, 0,pimage->GetWidth(), pimage->GetHeight()); delete pDC;
 
 
 
 
CImage时需要如下函数:
 
  1. BOOL LoadImageFromResource(CImage *pImage, UINT nResID,LPCTSTR lpTyp)
  2. { if ( pImage == NULL) return false;
  3. pImage->Destroy(); // 查找资源 HRSRC hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(nResID), lpTyp); if (hRsrc == NULL) return false; // 加载资源 HGLOBAL hImgData = ::LoadResource(AfxGetResourceHandle(), hRsrc); if (hImgData == NULL)
  4. {
  5. ::FreeResource(hImgData); return false;
  6. } // 锁定内存中的指定资源 LPVOID lpVoid = ::LockResource(hImgData);
  7. LPSTREAM pStream = NULL;
  8. DWORD dwSize = ::SizeofResource(AfxGetResourceHandle(), hRsrc);
  9. HGLOBAL hNew = ::GlobalAlloc(GHND, dwSize);
  10. LPBYTE lpByte = (LPBYTE)::GlobalLock(hNew);
  11. ::memcpy(lpByte, lpVoid, dwSize); // 解除内存中的指定资源 ::GlobalUnlock(hNew); // 从指定内存创建流对象 HRESULT ht = ::CreateStreamOnHGlobal(hNew, TRUE, &pStream); if ( ht != S_OK )
  12. {
  13. GlobalFree(hNew);
  14. } else { // 加载图片 pImage->Load(pStream);
  15. GlobalFree(hNew);
  16. } // 释放资源 ::FreeResource(hImgData); return true;
  17. }
 
这时加载图片的代码如下:
  1. HWND hwnd = GetSafeHwnd(); //获取窗口的HWND ::InvalidateRect( hwnd, NULL, true ); //或者 ::InvalidateRect( hwnd, NULL, false ); ::UpdateWindow(hwnd);
  2. CDC *pDC = GetDC();
  3. CImage Image;
  4. LoadImageFromResource(&Image,IDB_PNG1,_T("PNG")); if (Image.IsNull())
  5. {
  6. MessageBox(_T("没加载成功")); return;
  7. } if (Image.GetBPP() == 32) //确认该图像包含Alpha通道 { int i; int j; for (i=0; i<image.getwidth(); i++)="" {="" <span="">for (j=0; j<image.getheight(); j++)="" {="" byte="" *pbyte="(byte" *)image.getpixeladdress(i,="" j);="" pbyte[<span="">0] = pByte[0] * pByte[3] / 255;
  8. pByte[1] = pByte[1] * pByte[3] / 255;
  9. pByte[2] = pByte[2] * pByte[3] / 255;
  10. }
  11. }
  12. }
  13. Image.Draw(pDC->m_hDC,0,0);
  14. Image.Destroy();
  15. ReleaseDC(pDC);
 

要注意的是,最好把绘图放在OnPaint消息响应里,否则,OnSize消息触发OnPaint重绘时可能会把之前的绘图全部清除

 
 
 
 
 

vc++加载透明png图片方法-GDI+和CImage两种的更多相关文章

  1. 使用web.xml方式加载Spring时,获取Spring context的两种方式

    使用web.xml方式加载Spring时,获取Spring context的两种方式: 1.servlet方式加载时: [web.xml] <servlet> <servlet-na ...

  2. VC加载显示bmp图片的函数

    void ShowBitmap(HDC hdc,const char *srcpath) { HBITMAP hBitmap = (HBITMAP)::LoadImage(0, srcpath, IM ...

  3. Android-加载透明PNG图片变黑的问题

    png和jpg作为两种最常用的图片格式,首先我们要知道他们的区别: 1.从一般图片的外观上来说,他们是无法直接判断的 2.从文件大小上来说,同样一张图png肯定比jpg的大 3.通过查资料咱们可以发现 ...

  4. VC下加载多种格式图片的方法总结IPicture, CxImage, CImage(AtlImage), CPictureEx

    尽管VC有提供相应的API和类来操作bmp位图.图标和(增强)元文件,但却不支持jpg.gif和png等格式的图片,而这几种格式却是常常要用到的.这里我给大家介绍两种办法来操作这些格式的图片. 1.用 ...

  5. 图片懒加载插件lazyload使用方法

    图片懒加载插件lazyload使用方法 一.如何使用: Lazy Load 依赖于 jQuery.引入文件 <script type="text/javascript" sr ...

  6. 如何在启用SharePoint浏览器功能的InfoPath 表单中添加托管代码以动态地加载并显示图片

    InfoPath 的浏览器表单不支持加载并显示图片,当然在模板中可以插入图片,但是如果想显示数据库的一幅图片,或是动态加载一张图片就无能为力了. 基实这个问题可以通过在浏览器表单中使用: " ...

  7. cocos2dx中加载图片资源的方法,和从内存中获取已经加载的图片资源的方法

    游戏中通常需要将常用的资源如:声音,图片,plist文件,提前加载进内存,以加快游戏的流畅度 1.预加载声音: SimpleAudioEngine::getInstance()->preload ...

  8. iOS网络编程(三) 异步加载及缓存图片---->SDWebImage

    @SDWebImage提供一个UIImageView的类别以支持加载来自网络的远程图片.具有缓存管理.异步下载.同一个URL下载次数控制和优化等特征. @SDWebImage的导入1.https:// ...

  9. Android开发技巧——TextView加载HTML的图片及代码显示问题

    前几天在做一个Gradle用户指南的应用程序,使用的是TextView来加载HTML内容(至于为什么不用WebView,我也没有认真使用并比较过,也许以后会换吧),其中遇见了一些纠结的问题,所幸主要的 ...

随机推荐

  1. DevExpress去除多国语言包

    DevExpress作为windows开发中较为强大的第三方组件,能极大的提高编程效率和界面效果.但也要引用它较多的dll文件,它专门有个查看dll程序集依赖的工具,在VS的工具菜单下: 在VS的工具 ...

  2. 微信小程序 - this.triggerEvent()

    组件之间数据通信 调用组件wxml bind+组件内的方法名 <dialog bindclose="handleClose" bindopen="handleOpe ...

  3. vCenter Single Sign On 5.1 best practices

    http://www.virtualizationteam.com/virtualization-vmware/vsphere-virtualization-vmware/vcenter-single ...

  4. 实验室报告:VMware vSphere Data Protection

    dd Lab Reports VMware vSphere Data Protection Fast, Simple, and Agentless Deduplicated Virtual Machi ...

  5. 查看postgre都有哪些语句占用CPU,以及对应的sql语句

    查看占用CPU最多的几个postgresql ps aux | grep postgres | sort -n -r -k | head - | awk '{print $2, $3}' 查看所有po ...

  6. intellij idea 插件安装、卸载

    windows 下 intellij idea 插件安装.卸载   安装(在线安装): 根据图一.图二所示(蓝色标记) 卸载: 根据图一所示(橙色标记) 启用.关闭插件: 根据图一所示(绿色标记) 安 ...

  7. Webwork【01】Webwork与 Struct 的前世今生

    Struts 1是全世界第一个发布的MVC框架,它由Craig McClanahan在2001年发布,该框架一经推出,就得到了世界上Java Web开发者的拥护,经过长达6年时间的锤炼,Struts ...

  8. jQuery live事件说明及移除live事件方法

    1.live事件说明 jQuery1.3增加了一个live()方法,下面是手册上的说明: jQuery 1.3中新增的方法.给所有当前以及将来会匹配的元素绑定一个事件处理函数(比如click事件).也 ...

  9. 搭建ssm框架项目基本原理和主要的配置文件小结

    原文地址:https://blog.csdn.net/baidu_32739019/article/details/73928040 1.springmvc是spring框架的一个模块,springm ...

  10. mysql导入source注意点

    mysql的导入导出要注意字符集,防止查询乱码! 导入前设置字符集 set names utf8; //导入指定编码source /xxx.sqlcommit;