※先给大家认识下什么是WIC
WIC全称是Windows Image Component,是一套扩展的API,用来处理数字图像,它是基于COM组件的。该API包含非常丰富的图像处理函数。
详细可以点击百度文库再看看 http://baike.baidu.com/view/414115.htm?fr=aladdin
看过D2D的使用(1)http://blog.csdn.net/bojie5744/article/details/29825093,我想也会熟悉了一点绘图的步骤了吧?
下面就怎么实现加载图片资源来说一下(5个步骤,实现代码比较长)。为了方便,讲解代码和上一次发的“D2D的使用(1)”结合。
1.(注意:代码接着上一次的)
在原来画矩形的基础上添加一些变量,还有头文件和链接
#include <wincodec.h>
#pragma comment(lib,"Windowscodecs.lib")//创建WIC com需要
ID2D1Bitmap* m_pD2d1Bitmap = NULL;
IWICBitmap* m_pWicBitmap = NULL;
IWICImagingFactory* m_pWicImagingFactory = NULL;
IWICBitmapDecoder* m_pWicDecoder = NULL;
IWICBitmapFrameDecode* m_pWicFrameDecoder = NULL;
2.在创建D2D渲染器后,创建WIC com接口(其实2者没有什么先后创建的顺序,就是方便讲解)
CoCreateInstance(CLSID_WICImagingFactory,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&m_pWicImagingFactory));
3.用WIC加载图片,然后把WIC转换为D2D兼容的图片显示。
if(m_pWicImagingFactory != NULL)
{
m_pWicImagingFactory->CreateDecoderFromFilename(L"C:/a.bmp",nullptr,GENERIC_READ,WICDecodeMetadataCacheOnDemand,&m_pWicDecoder);
//"C:/a.bmp"为你的图片资源地址
m_pWicDecoder->GetFrame(0,&m_pWicFrameDecoder);
IWICBitmapSource* pWicSource = NULL;
m_pWicFrameDecoder->QueryInterface(IID_PPV_ARGS(&pWicSource));
IWICFormatConverter* pCovert = NULL;
m_pWicImagingFactory->CreateFormatConverter(&pCovert);
pCovert->Initialize(
pWicSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeCustom
);
m_pWicImagingFactory->CreateBitmapFromSource(pCovert,WICBitmapCacheOnDemand,&m_pWicBitmap);
UINT pixelWidth = 0,pixelHeight = 0;
m_pWicBitmap->GetSize(&pixelWidth,&pixelHeight);
SAFE_RELEASE(pCovert);
}
pRenderTarget->CreateBitmapFromWicBitmap(m_pWicBitmap,NULL,&m_pD2d1Bitmap);
4.在绘图区域中添加代码实现图片的绘制
绘图区域是:
pRenderTarget->BeginDraw() ;
//绘图区域
hr = pRenderTarget->EndDraw() ;
里面的代码以下:
D2D1_SIZE_F rtSize = pRenderTarget->GetSize();
if(m_pD2d1Bitmap != NULL)
{
D2D1_SIZE_U sizeU = m_pD2d1Bitmap->GetPixelSize();
D2D1_RECT_F rectangle3 = D2D1::RectF(
(rtSize.width - sizeU.width)*0.5f,
(rtSize.height - sizeU.height)*0.5f,
sizeU.width + (rtSize.width - sizeU.width)*0.5f ,
sizeU.height + (rtSize.height - sizeU.height)*0.5f
);
pRenderTarget->DrawBitmap(m_pD2d1Bitmap,&rectangle3,1.0f);
}
就这样就好了。最后就是释放指针。
以下就是完整的代码和演示效果:
ID2D1Factory* pD2DFactory = NULL;
ID2D1HwndRenderTarget* pRenderTarget=NULL;//用来在窗口中进行渲染
ID2D1SolidColorBrush* pBlackBrush=NULL;//定义画刷,用来绘制图形
ID2D1RadialGradientBrush* pRadialGradientBrush=NULL;
#define SAFE_RELEASE(p) if(p){p->Release() ; p = NULL ;}
ID2D1Bitmap* m_pD2d1Bitmap;
IWICBitmap* m_pWicBitmap;
IWICImagingFactory* m_pWicImagingFactory;
IWICBitmapDecoder* m_pWicDecoder;
IWICBitmapFrameDecode* m_pWicFrameDecoder;
VOID MyDraw(HWND hwnd)
{
HRESULT hr;
RECT rc={0,0,500,500};//渲染矩形大小
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory) ;
if(!SUCCEEDED(hr))
{
MessageBox(hwnd,"创建D2D设备出错","Error",0);
}
hr = pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(
hwnd,
D2D1::SizeU(rc.right - rc.left,rc.bottom - rc.top)),
&pRenderTarget) ;
if(!SUCCEEDED(hr))
{
MessageBox(hwnd,"创建渲染器失败","Error",0);
}
hr = CoCreateInstance(CLSID_WICImagingFactory,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&m_pWicImagingFactory));
if(m_pWicImagingFactory != nullptr)
{
m_pWicImagingFactory->CreateDecoderFromFilename(L"C:/a.bmp",nullptr,GENERIC_READ,WICDecodeMetadataCacheOnDemand,&m_pWicDecoder);
m_pWicDecoder->GetFrame(0,&m_pWicFrameDecoder);
IWICBitmapSource* pWicSource = nullptr;
m_pWicFrameDecoder->QueryInterface(IID_PPV_ARGS(&pWicSource));
IWICFormatConverter* pCovert = nullptr;
m_pWicImagingFactory->CreateFormatConverter(&pCovert);
hr = pCovert->Initialize(
pWicSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeCustom
);
m_pWicImagingFactory->CreateBitmapFromSource(pCovert,WICBitmapCacheOnDemand,&m_pWicBitmap);
SAFE_RELEASE(pCovert);
UINT pixelWidth = 0,pixelHeight = 0;
m_pWicBitmap->GetSize(&pixelWidth,&pixelHeight);
}
pRenderTarget->CreateBitmapFromWicBitmap(m_pWicBitmap,NULL,&m_pD2d1Bitmap);
hr = pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Red),&pBlackBrush);
if(!SUCCEEDED(hr))
{
MessageBox(hwnd,"创建失败","Error",0);
}
pRenderTarget->BeginDraw() ;
pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White,0));
/*****************绘制图片*************************/
D2D1_SIZE_F rtSize = pRenderTarget->GetSize();
if(m_pD2d1Bitmap != nullptr)
{
D2D1_SIZE_U sizeU = m_pD2d1Bitmap->GetPixelSize();
D2D1_RECT_F rectangle3 = D2D1::RectF(
(rtSize.width - sizeU.width)*0.5f,
(rtSize.height - sizeU.height)*0.5f,
sizeU.width + (rtSize.width - sizeU.width)*0.5f ,
sizeU.height + (rtSize.height - sizeU.height)*0.5f
);
pRenderTarget->DrawBitmap(m_pD2d1Bitmap,&rectangle3,1.0f);
}
/*****************绘制图片*************************/
/*****************绘制矩形*************************/
pRenderTarget->DrawRectangle(
D2D1::RectF(
rc.left + 100.0f,
rc.top + 100.0f,
rc.right - 100.0f,
rc.bottom - 100.0f),
pBlackBrush);
/*****************绘制矩形*************************/
pRenderTarget->EndDraw() ;
SAFE_RELEASE(m_pWicBitmap);//这个图片资源记得释放,不然会不断增加内存,不然,你可以把它创建完后,就不要再创建,到程序结束后再释放。
SAFE_RELEASE(pBlackBrush) ;
SAFE_RELEASE(pRadialGradientBrush);
}
由于编写比较急,有很多判断没有写,还有可以有些地方需要释放指针的没有释放(有空会改回来)。读者可以自行修改下,代码的实现
是没有问题的。
直接在OnPaint()函数中添加MyDraw(m_hWnd);就好了。