如何通过Win32 API在不使用GDI的情况下高效加载PNG图像?
- 内容介绍
- 文章标签
- 相关推荐
本文共计322个文字,预计阅读时间需要2分钟。
可以使用Win32+GDI函数将PNG从文件加载到HBITMAP中。如果没有使用外部库(如libpng),最轻量级的解决方案是使用Windows Imaging Component(WIC)来加载PNG文件。以下是使用WIC加载PNG文件的示例代码:
cpp#include #include
HBITMAP LoadPNGToHBITMAP(const wchar_t* filePath) { IStream* pStream=NULL; IWICImagingFactory* pFactory=NULL; IWICBitmapDecoder* pDecoder=NULL; IWICBitmap* pBitmap=NULL; HBITMAP hBitmap=NULL;
HRESULT hr=S_OK;
// 创建WIC工厂 hr=CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void**)&pFactory); if (FAILED(hr)) return NULL;
// 打开文件流 hr=CreateFileW(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL, &pStream); if (FAILED(hr)) { pFactory->Release(); return NULL; }
// 创建WIC流 hr=pFactory->CreateStreamFromHandle(pStream, 0, NULL, &pDecoder); pStream->Release(); if (FAILED(hr)) return NULL;
// 解码PNG文件 hr=pDecoder->GetFrame(0, &pBitmap); pDecoder->Release(); if (FAILED(hr)) return NULL;
// 创建HBITMAP BITMAP bmp; pBitmap->GetSize(&bmp); bmp.bmWidth=bmp.bmWidthMM / GetDeviceCaps(GetDC(NULL), LOGPIXELSX); bmp.bmHeight=bmp.bmHeightMM / GetDeviceCaps(GetDC(NULL), LOGPIXELSY); bmp.bmWidthBytes=(bmp.bmWidth * 32 + 31) / 32 * 4; bmp.bmPlanes=1; bmp.bmBitsPixel=32; bmp.bmBits=GlobalAlloc(GMEM_MOVEABLE, bmp.bmWidthBytes * bmp.bmHeight); HBITMAP hOldBitmap=(HBITMAP)SelectObject((HDC)GetDC(NULL), (HBITMAP)bmp.bmBits);
// 将WIC位图复制到HBITMAP pBitmap->CopyPixels(NULL, bmp.bmWidthBytes, bmp.bmHeight, (UINT*)bmp.bmBits);
hBitmap=(HBITMAP)bmp.bmBits; SelectObject((HDC)GetDC(NULL), hOldBitmap); pBitmap->Release();
pFactory->Release();
return hBitmap;}
是否可以使用Win32 GDI函数将PNG从文件加载到HBITMAP中?如果没有,没有使用外部库(如libpng),最轻的解决方案是什么? 您可以使用 Windows Imaging Component加载PNG文件(在Windows XP SP2及更高版本上).有关如何使用API和 my blog post的介绍,请参阅 MSDN Magazine,以获取从IStream加载PNG并将其转换为HBITMAP的代码示例.本文共计322个文字,预计阅读时间需要2分钟。
可以使用Win32+GDI函数将PNG从文件加载到HBITMAP中。如果没有使用外部库(如libpng),最轻量级的解决方案是使用Windows Imaging Component(WIC)来加载PNG文件。以下是使用WIC加载PNG文件的示例代码:
cpp#include #include
HBITMAP LoadPNGToHBITMAP(const wchar_t* filePath) { IStream* pStream=NULL; IWICImagingFactory* pFactory=NULL; IWICBitmapDecoder* pDecoder=NULL; IWICBitmap* pBitmap=NULL; HBITMAP hBitmap=NULL;
HRESULT hr=S_OK;
// 创建WIC工厂 hr=CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void**)&pFactory); if (FAILED(hr)) return NULL;
// 打开文件流 hr=CreateFileW(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL, &pStream); if (FAILED(hr)) { pFactory->Release(); return NULL; }
// 创建WIC流 hr=pFactory->CreateStreamFromHandle(pStream, 0, NULL, &pDecoder); pStream->Release(); if (FAILED(hr)) return NULL;
// 解码PNG文件 hr=pDecoder->GetFrame(0, &pBitmap); pDecoder->Release(); if (FAILED(hr)) return NULL;
// 创建HBITMAP BITMAP bmp; pBitmap->GetSize(&bmp); bmp.bmWidth=bmp.bmWidthMM / GetDeviceCaps(GetDC(NULL), LOGPIXELSX); bmp.bmHeight=bmp.bmHeightMM / GetDeviceCaps(GetDC(NULL), LOGPIXELSY); bmp.bmWidthBytes=(bmp.bmWidth * 32 + 31) / 32 * 4; bmp.bmPlanes=1; bmp.bmBitsPixel=32; bmp.bmBits=GlobalAlloc(GMEM_MOVEABLE, bmp.bmWidthBytes * bmp.bmHeight); HBITMAP hOldBitmap=(HBITMAP)SelectObject((HDC)GetDC(NULL), (HBITMAP)bmp.bmBits);
// 将WIC位图复制到HBITMAP pBitmap->CopyPixels(NULL, bmp.bmWidthBytes, bmp.bmHeight, (UINT*)bmp.bmBits);
hBitmap=(HBITMAP)bmp.bmBits; SelectObject((HDC)GetDC(NULL), hOldBitmap); pBitmap->Release();
pFactory->Release();
return hBitmap;}
是否可以使用Win32 GDI函数将PNG从文件加载到HBITMAP中?如果没有,没有使用外部库(如libpng),最轻的解决方案是什么? 您可以使用 Windows Imaging Component加载PNG文件(在Windows XP SP2及更高版本上).有关如何使用API和 my blog post的介绍,请参阅 MSDN Magazine,以获取从IStream加载PNG并将其转换为HBITMAP的代码示例.
