[Direct2D开发] 从资源加载位图
一、概述
Direct2D使用Windows图像处理组件 (WIC) 来加载位图。从文件加载位图的方法很简单,而且网上的教程也很多,相信大家都非常熟悉了。但是如果需要从资源加载位图,该怎么做呢?
从资源加载Direct2D位图的需求是很常见的,但是网上关于从资源加载位图的资料很少。折腾了很久终于找到了解决方法,贴到这里供大家参考。
二、从资源加载位图
1.在应用程序资源定义文件中定义资源。下面代码为resource.h中的资源id:
1 2 3 4 5 | //{{NO_DEPENDENCIES}} // Microsoft Visual C generated include file. // Used by D2DCreateBitmapFromResource.rc // #define IDB_PNG1 101 |
此资源会在生成应用程序时添加到应用程序的资源文件中。
2.从应用程序资源文件加载图像。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | HRESULT LoadResourceBitmap( ID2D1RenderTarget *pRenderTarget, IWICImagingFactory *pIWICFactory, PCWSTR resourceName, PCWSTR resourceType, UINT destinationWidth, UINT destinationHeight, ID2D1Bitmap **ppBitmap) { IWICBitmapDecoder *pDecoder = NULL; IWICBitmapFrameDecode *pSource = NULL; IWICStream *pStream = NULL; IWICFormatConverter *pConverter = NULL; IWICBitmapScaler *pScaler = NULL; HRSRC imageResHandle = NULL; HGLOBAL imageResDataHandle = NULL; void *pImageFile = NULL; DWORD imageFileSize = 0; // Locate the resource. imageResHandle = FindResourceW(HINST_THISCOMPONENT, resourceName, resourceType); HRESULT hr = imageResHandle ? S_OK : E_FAIL; if (SUCCEEDED(hr)) { // Load the resource. imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle); hr = imageResDataHandle ? S_OK : E_FAIL; } |
3.锁定资源并计算图像的大小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | if (SUCCEEDED(hr)) { // Lock it to get a system memory pointer. pImageFile = LockResource(imageResDataHandle); hr = pImageFile ? S_OK : E_FAIL; } if (SUCCEEDED(hr)) { // Calculate the size. imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle); hr = imageFileSize ? S_OK : E_FAIL; } |
4.使用 IWICImagingFactory::CreateStream 方法创建 IWICStream 对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 | if (SUCCEEDED(hr)) { // Create a WIC stream to map onto the memory. hr = pIWICFactory->CreateStream(&pStream); } if (SUCCEEDED(hr)) { // Initialize the stream with the memory pointer and size. hr = pStream->InitializeFromMemory( reinterpret_cast < BYTE *>(pImageFile), imageFileSize ); } |
5.使用 IWICImagingFactory::CreateDecoderFromStream 方法创建 IWICBitmapDecoder。
1 2 3 4 5 6 7 8 9 10 | if (SUCCEEDED(hr)) { // Create a decoder for the stream. hr = pIWICFactory->CreateDecoderFromStream( pStream, NULL, WICDecodeMetadataCacheOnLoad, &pDecoder ); } |
6.从图像中检索某一帧并将该帧存储在 IWICBitmapFrameDecode 对象中。
1 2 3 4 5 | if (SUCCEEDED(hr)) { // Create the initial frame. hr = pDecoder->GetFrame(0, &pSource); } |
7.必须先将图像转换为 32bppPBGRA 像素格式,然后 Direct2D 才能使用该图像。若要转换图像格式,请使用IWICImagingFactory::CreateFormatConverter 方法创IWICFormatConverter 对象,然后使用 IWICFormatConverter 对象的Initialize 方法执行转换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | if (SUCCEEDED(hr)) { // Convert the image format to 32bppPBGRA // (DXGI_FORMAT_B8G8R8A8_UNORM D2D1_ALPHA_MODE_PREMULTIPLIED). hr = pIWICFactory->CreateFormatConverter(&pConverter); } if (SUCCEEDED(hr)) { hr = pConverter->Initialize( pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut ); } |
8.最后,使用 CreateBitmapFromWicBitmap 方法创建 ID2D1Bitmap 对象,该对象可通过呈现器目标绘制并与其他 Direct2D 对象一起使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | if (SUCCEEDED(hr)) { //create a Direct2D bitmap from the WIC bitmap. hr = pRenderTarget->CreateBitmapFromWicBitmap( pConverter, NULL, ppBitmap ); } SafeRelease(&pDecoder); SafeRelease(&pSource); SafeRelease(&pStream); SafeRelease(&pConverter); SafeRelease(&pScaler); return hr; } |
绘制效果图如下:
本文中只列出了部分代码。有关完整代码,请点击此处下载,源码为Direct2DTests中的D2DCreateBitmapFromResource文件。
大家在使用此方法加载图片资源时,不要加载.bmp格式的图片,这样会导致加载失败,尽量使用.png或.jpg格式的图片资源进行加载。
出处:http://www.cnblogs.com/Ray1024/
版权声明:本文的版权归作者与博客园共有。转载时须注明本文的作者及详细链接,否则作者将保留追究其法律责任。
欢迎大家学习、共享,如果文章中有错误或漏洞,请大家在评论区留言!!