vc++加载透明png图片方法——GDI+和CImage两种
来源:互联网 发布:优化的条件 英文 编辑:程序博客网 时间:2024/04/29 04:27
vc++加载透明png图片方法——GDI+和CImage两种
分类:
目录(?)[+]
先看看GDI+的方法
方法1:
1.GDI+画透明图层(alpha)的png图片
stdafx加入如下:
#include <comdef.h>//初始化一下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 objectImage image(_T("1.png")); // Construct an imagegraphics.DrawImage(&image, 0, 0, image.GetWidth(), image.GetHeight());delete pDC;
这是用GDI+来显示图片。
2.CImage绘制带alpha透明图层的png图片
用MFC自带的CImage也可以显示,不过要稍微进行转换才能得到正常的带α通道的png图片!
在画图前进行一次转换,其中Image是CImage的对象
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.如果图片是在资源里的时候加载方法又不一样
这时需要两个函数,
对于GDI+如下:
BOOL ImageFromIDResource(UINT nID, LPCTSTR sTR,Image *&pImg){HINSTANCE hInst = AfxGetResourceHandle();HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // typeif (!hRsrc)return FALSE;// load resource into memoryDWORD len = SizeofResource(hInst, hRsrc);BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);if (!lpRsrc)return FALSE;// Allocate global memory on which to create streamHGLOBAL 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 streampImg=Gdiplus::Image::FromStream(pstm);// free/release stuffpstm->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 objectImage *pimage; // Construct an imageImageFromIDResource(IDB_PNG1,_T("PNG"),pimage);graphics.DrawImage(pimage, 0, 0,pimage->GetWidth(), pimage->GetHeight());delete pDC;
用CImage时需要如下函数:
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++){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);
另
要注意的是,最好把绘图放在OnPaint消息响应里,否则,OnSize消息触发OnPaint重绘时可能会把之前的绘图全部清除
0 0
- vc++加载透明png图片方法——GDI+和CImage两种
- vc++加载透明png图片方法——GDI+和CImage两种
- vc++加载透明png图片方法——GDI+和CImage两种
- VC++加载透明png图片的两种常用方法——GDI+和CImage
- vc++加载透明png图片方法——GDI+和CImage两种
- vc++加载透明png图片方法——GDI+和CImage两种
- vc++加载透明png图片方法——GDI+和CImage两种
- vc++加载透明png图片方法——GDI+和CImage两种
- vc++加载透明png图片方法——GDI+和CImage两种
- vc++加载透明png图片方法——GDI+和CImage两种
- vc++加载透明png图片方法——GDI+和CImage两种
- vc++加载透明png图片方法——GDI+和CImage两种 ,vs2005 vs2008 PNG背景
- vc++加载透明png图片方法——GDI+和CImage两种 ,vs2005 vs2008 PNG背景
- vc++加载透明png图片方法——GDI+和CImage两种 ,vs2005 vs2008 PNG背景
- [vc] vc++加载透明png图片的两种方法-GDI+和CImage
- vc++加载透明png图片的两种方法-GDI+和CImage
- 加载png图片的两种方法 - GDI+和CImage
- 加载png图片的两种方法 - GDI+和CImage
- 真正的爱情,是他为你改变自我,是妥协和容忍
- 贝叶斯分类器,最小二乘
- redis数据类型 - set类型
- scala 数组Array排序,转换字符串,过滤 quickSort,mkString,yield,filter,map
- plsql 导入excel文件和txt文件
- vc++加载透明png图片方法——GDI+和CImage两种
- 自绘贴图-MFC方式
- SpringMVC中,前台jsp封装参数,绑定参数,传递参数到后台controller的过程详解
- Masonry框架
- 怎样运用EDIUS中的色彩平衡滤镜较色
- ThreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别
- 探秘Java中String、StringBuilder以及StringBuffer
- 单例模式
- java String 两种不同的赋值 比较