HRESULT LoadImageFormFile(
ID2D1RenderTarget *pRT,
IWICImagingFactory *pWicFactory,
PCTSTR url,
UINT dstWidth,
UINT dstHeight,
ID2D1Bitmap **ppBitmap
)
{
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pFrame = NULL;
IWICFormatConverter *pFormat = NULL;
IWICBitmapScaler *pScaler = NULL;
HRESULT hr = pWicFactory->CreateDecoderFromFilename(
url,
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if ( SUCCEEDED(hr) )
{
hr = pDecoder->GetFrame(0, &pFrame);
}
if ( SUCCEEDED(hr) )
{
hr = pWicFactory->CreateFormatConverter(&pFormat);
}
if ( SUCCEEDED(hr) )
{
if ( dstWidth != 0 || dstHeight != 0)
{
UINT originalWidth, originalHeight;
hr = pFrame->GetSize(&originalWidth, &originalHeight);
if ( SUCCEEDED(hr) )
{
if ( dstWidth == 0 )
{
FLOAT scalar = (FLOAT)dstHeight / (FLOAT)originalHeight;
dstWidth = (UINT)(scalar * (FLOAT)originalWidth);
}
else
{
FLOAT scalar = (FLOAT)dstWidth / (FLOAT)originalWidth;
dstHeight = (UINT)(scalar * (FLOAT)originalHeight);
}
hr = pWicFactory->CreateBitmapScaler(&pScaler);
}
if ( SUCCEEDED(hr) )
{
hr = pScaler->Initialize(
pFrame,
dstWidth,
dstHeight,
WICBitmapInterpolationModeCubic
);
}
if ( SUCCEEDED(hr) )
{
hr = pFormat->Initialize(
pScaler,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.0f,
WICBitmapPaletteTypeMedianCut
);
}
}
else
{
hr = pFormat->Initialize(
pFrame,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.0f,
WICBitmapPaletteTypeMedianCut
);
}
}
if ( SUCCEEDED(hr) )
{
hr = pRT->CreateBitmapFromWicBitmap(
pFormat,
ppBitmap
);
}
SafeRelease(pDecoder);
SafeRelease(pFrame);
SafeRelease(pFormat);
SafeRelease(pScaler);
return hr;
}
Direct 2D本身不能加载位图, 需要通过WIC接口.
#include <wincodec.h>
#pragma comment(lib, "Windowscodecs.lib")
首先 使用 CoCreateInstance 构造一个 IWicImaginFactory 对象.
IWicImaginFactory 对象用于创建所有 WIC 对象.
步骤:
1,
IWICImagingFactory::CreateDecoderFromFilename(...) 函数从 文件 加载位图.
该函数产生一个 IWICBitmapDecoder 对象.
该对象指向位图数据.
2,
IWICBitmapDecoder::GetSize(...) 函数从 位图数据 中读取一帧图像的数据.
该函数产生一个 IWICBitmapFrameDecode 对象.
该对象指向位图某一帧图像数据.
3,
IWICBitmapScaler::Initialize(...) 函数将 图像缩放.
如果不需要缩放, 此步骤可以省略.
4,
IWICFormatConverter::Initialize(...) 函数将 图像数据 转换格式, 使得Direct 2D能够识别.
5,
ID2D1HwndRenderTarget::CreateBitmapFromWicBitmap(...)
通过传入的 图像数据 创建 ID2D1Bitmap 对象.
前面4步都是由WIC完成, 只有最后一步使用Direct 2D完成.
创建的位图是设备相关资源, 在设备丢失之后需要重新创建.