vc++加载透明png图片方法-GDI+和CImage两种
转载自:http://blog.csdn.net/zhongbin104/article/details/8730935
先看看GDI+的方法
方法1:
1.GDI+画透明图层(alpha)的png图片
stdafx加入如下:
#include //初始化一下com口 #include "GdiPlus.h" using namespace Gdiplus; #pragma comment(lib,"gdiplus.lib")
开始初始化:
在app类的声明里(.h)加入:
ULONG_PTR m_gdiplusToken;
InitInstance()里加入://若没有usingnamespace Gdiplus; 就要在前面加Gdiplus::
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
重载ExitInstance,加入GdiplusShutdown(m_gdiplusToken);
int CxxxApp::ExitInstance()
{ // TODO: 在此添加专用代码和/或调用基类 GdiplusShutdown(m_gdiplusToken); return CWinApp::ExitInstance();
}
显示图片的过程如下
CClientDC *pDC = new CClientDC(GetDlgItem(IDC_STATIC_PIC));
CRect rect;
GetDlgItem(IDC_STATIC_PIC)->GetWindowRect(&rect);
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图片!
if (Image.GetBPP() == 32) //确认该图像包含Alpha通道 { int i; int j; for (i = 0; i < Image.GetWidth(); i++)
{ for (j = 0; j < Image.GetHeight(); j++)
{
byte *pByte = (byte *)Image.GetPixelAddress(i, j);
pByte[0] = pByte[0] * pByte[3] / 255;
pByte[1] = pByte[1] * pByte[3] / 255;
pByte[2] = pByte[2] * pByte[3] / 255;
}
}
}
具体方法如下:
HWND hwnd = GetSafeHwnd(); //获取窗口的HWND ::InvalidateRect( hwnd, NULL, true ); //或者 ::InvalidateRect( hwnd, NULL, false ); ::UpdateWindow(hwnd); //若使用前不想把原来绘制的图片去掉,可以删去上面那三段 CDC *pDC = GetDC();
CImage Image;
Image.Load(strPath); if (Image.IsNull())
{
MessageBox(_T("没加载成功")); return -1;
} if (Image.GetBPP() == 32) //确认该图像包含Alpha通道 { int i; int j; for (i = 0; i < Image.GetWidth(); i++)
{ for (j = 0; j < Image.GetHeight(); j++)
{
byte *pByte = (byte *)Image.GetPixelAddress(i, j);
pByte[0] = pByte[0] * pByte[3] / 255;
pByte[1] = pByte[1] * pByte[3] / 255;
pByte[2] = pByte[2] * pByte[3] / 255;
}
}
}
Image.Draw(pDC->m_hDC, 0, 0);
Image.Destroy();
ReleaseDC(pDC);


3.如果图片是在资源里的时候加载方法又不一样
BOOL ImageFromIDResource(UINT nID, LPCTSTR sTR,Image *&pImg)
{
HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type if (!hRsrc) return FALSE; // load resource into memory DWORD len = SizeofResource(hInst, hRsrc);
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);
BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
memcpy(pmem,lpRsrc,len);
GlobalUnlock(m_hMem);
IStream* pstm;
CreateStreamOnHGlobal(m_hMem,FALSE,&pstm); // load from stream pImg=Gdiplus::Image::FromStream(pstm); // free/release stuff pstm->Release();
FreeResource(lpRsrc);
GlobalFree(m_hMem); return TRUE;
}
CClientDC *pDC = new CClientDC(GetDlgItem(IDC_STATIC_PIC));
CRect rect;
GetDlgItem(IDC_STATIC_PIC)->GetWindowRect(&rect);
Graphics graphics(pDC->m_hDC); // Create a GDI+ graphics object Image *pimage; // Construct an image ImageFromIDResource(IDB_PNG1,_T("PNG"),pimage);
graphics.DrawImage(pimage, 0, 0,pimage->GetWidth(), pimage->GetHeight()); delete pDC;
BOOL LoadImageFromResource(CImage *pImage, UINT nResID,LPCTSTR lpTyp)
{ if ( pImage == NULL) return false;
pImage->Destroy(); // 查找资源 HRSRC hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(nResID), lpTyp); if (hRsrc == NULL) return false; // 加载资源 HGLOBAL hImgData = ::LoadResource(AfxGetResourceHandle(), hRsrc); if (hImgData == NULL)
{
::FreeResource(hImgData); return false;
} // 锁定内存中的指定资源 LPVOID lpVoid = ::LockResource(hImgData);
LPSTREAM pStream = NULL;
DWORD dwSize = ::SizeofResource(AfxGetResourceHandle(), hRsrc);
HGLOBAL hNew = ::GlobalAlloc(GHND, dwSize);
LPBYTE lpByte = (LPBYTE)::GlobalLock(hNew);
::memcpy(lpByte, lpVoid, dwSize); // 解除内存中的指定资源 ::GlobalUnlock(hNew); // 从指定内存创建流对象 HRESULT ht = ::CreateStreamOnHGlobal(hNew, TRUE, &pStream); if ( ht != S_OK )
{
GlobalFree(hNew);
} else { // 加载图片 pImage->Load(pStream);
GlobalFree(hNew);
} // 释放资源 ::FreeResource(hImgData); return true;
}
HWND hwnd = GetSafeHwnd(); //获取窗口的HWND ::InvalidateRect( hwnd, NULL, true ); //或者 ::InvalidateRect( hwnd, NULL, false ); ::UpdateWindow(hwnd);
CDC *pDC = GetDC();
CImage Image;
LoadImageFromResource(&Image,IDB_PNG1,_T("PNG")); if (Image.IsNull())
{
MessageBox(_T("没加载成功")); return;
} 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;
pByte[1] = pByte[1] * pByte[3] / 255;
pByte[2] = pByte[2] * pByte[3] / 255;
}
}
}
Image.Draw(pDC->m_hDC,0,0);
Image.Destroy();
ReleaseDC(pDC);
vc++加载透明png图片方法-GDI+和CImage两种的更多相关文章
- 使用web.xml方式加载Spring时,获取Spring context的两种方式
使用web.xml方式加载Spring时,获取Spring context的两种方式: 1.servlet方式加载时: [web.xml] <servlet> <servlet-na ...
- VC加载显示bmp图片的函数
void ShowBitmap(HDC hdc,const char *srcpath) { HBITMAP hBitmap = (HBITMAP)::LoadImage(0, srcpath, IM ...
- Android-加载透明PNG图片变黑的问题
png和jpg作为两种最常用的图片格式,首先我们要知道他们的区别: 1.从一般图片的外观上来说,他们是无法直接判断的 2.从文件大小上来说,同样一张图png肯定比jpg的大 3.通过查资料咱们可以发现 ...
- VC下加载多种格式图片的方法总结IPicture, CxImage, CImage(AtlImage), CPictureEx
尽管VC有提供相应的API和类来操作bmp位图.图标和(增强)元文件,但却不支持jpg.gif和png等格式的图片,而这几种格式却是常常要用到的.这里我给大家介绍两种办法来操作这些格式的图片. 1.用 ...
- 图片懒加载插件lazyload使用方法
图片懒加载插件lazyload使用方法 一.如何使用: Lazy Load 依赖于 jQuery.引入文件 <script type="text/javascript" sr ...
- 如何在启用SharePoint浏览器功能的InfoPath 表单中添加托管代码以动态地加载并显示图片
InfoPath 的浏览器表单不支持加载并显示图片,当然在模板中可以插入图片,但是如果想显示数据库的一幅图片,或是动态加载一张图片就无能为力了. 基实这个问题可以通过在浏览器表单中使用: " ...
- cocos2dx中加载图片资源的方法,和从内存中获取已经加载的图片资源的方法
游戏中通常需要将常用的资源如:声音,图片,plist文件,提前加载进内存,以加快游戏的流畅度 1.预加载声音: SimpleAudioEngine::getInstance()->preload ...
- iOS网络编程(三) 异步加载及缓存图片---->SDWebImage
@SDWebImage提供一个UIImageView的类别以支持加载来自网络的远程图片.具有缓存管理.异步下载.同一个URL下载次数控制和优化等特征. @SDWebImage的导入1.https:// ...
- Android开发技巧——TextView加载HTML的图片及代码显示问题
前几天在做一个Gradle用户指南的应用程序,使用的是TextView来加载HTML内容(至于为什么不用WebView,我也没有认真使用并比较过,也许以后会换吧),其中遇见了一些纠结的问题,所幸主要的 ...
随机推荐
- IO multiplexing 与 非阻塞网络编程
使用I/O multipexing 的网络编程中,一般需要采用非阻塞网络编程的风格,防止服务端在处理高连接量大时候阻塞在某个文件描述符上面,比如某个socket 有大量的数据需要写,但是内核发送缓冲区 ...
- vsphere脚本等
- Java常用的非受检异常
IllegalArgumentException 非 null 的参数值不正确 IllegalStateException 对于方法调用而言,对象状态不合适 NullPointException 参数 ...
- Android插件化开发之解决OpenAtlas组件在宿主的注冊问题
OpenAtlas有一个问题,就是四大组件必须在Manifest文件里进行注冊,那么就必定带来一个问题,插件中的组件都要反复在宿主中注冊.像Service,ContentProvider等组件眼下没有 ...
- Makefile 和 CMakeLists.txt
Makefile Makefile 的格式 target: prerequisites [tab]command 例子 #Makefile all:chap1 chap2 chap1: - - - : ...
- Linux十大常用命令
No 命令 功能 实例 解释 mkdir 创建目录 mkdir newdirmkdir dir/subdirmkdir -p newdir/subdir -p: 可以是一个路径名称.此时若路径中的某些 ...
- oracle 、mysql、 sql server使用记录
oracle .mysql. sql server使用记录 mysql常用命令: mysqld --启动mysql数据库 show databases; -- 查看数据库 use database; ...
- linux下的文本编辑器VI的使用命令
1. 移动光标 H #移到屏幕的左上角 M #移到屏幕的中间行开头 L #移到屏幕的最后一行 [ #移到文件开始位置 (双击) ] #移到文件结束位置(双击) :n #移到文件的第n行 Ctrl + ...
- js代码实现购物车效果
页面分上下两部分,上部分是所有的数据,下部分是购物车.通过在上面选择需要处理的数据添加进到购物车,实现对购物车数据的统一处理. 需要注意的有两点:①购物车数据可删除,且不能重复添加 ②响应时间考虑,购 ...
- 一个死去的网站shige.laiyo.com
2017年4月份的时候,研一下刚刚开始. 爬了这个网站,现在这个网站已经关闭了,这些爬虫代码也就没用了,面向特定网站爬虫本身就是没有意义的. 爬author import requests from ...