Direct2DでイメージファイルであるPNGを表示する方法。



ID2D1RenderTarget* cxt = ...

CComPtr bmp;
D2DResource::LoadImage( cxt, L"e:\test\images\abc.png", &bmp );
// auto image_size = bmp->GetPixelSize(); イメージの大きさ

//リソースから読み込む場合
//CComPtr bmp;
//D2DResource::LoadImage( cxt, L"png", IDB_PNG1, &bmp );

D2D1_RECT_U rc = ...

cxt->DrawBitmap( bmp, rc );


/////////////////////////////////////////////////////////////////////////////////////////////////////
class D2DResource
{
public :
static bool LoadImage ( ID2D1RenderTarget* target, LPCWSTR filenm, ID2D1Bitmap** bmp );
static bool LoadImage ( ID2D1RenderTarget* target, LPCWSTR resource_section, int resource_id, ID2D1Bitmap** bmp );
static bool LoadImage2( ID2D1RenderTarget* target, IWICImagingFactory* pWICFactory, IWICStream* pStream, ID2D1Bitmap** bmp );
};


bool D2DResource::LoadImage( ID2D1RenderTarget* target, LPCWSTR filenm, ID2D1Bitmap** bmp )
{
HRESULT hr;
CComPtr pStream;
CComPtr pWICFactory;

hr = CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_ALL, __uuidof(IWICImagingFactory), (void**)&pWICFactory );
if ( hr != S_OK ) return false;
hr = pWICFactory->CreateStream( &pStream );
if ( hr != S_OK ) return false;
hr = pStream->InitializeFromFilename( filenm, GENERIC_READ); // bmp,gif,jpg,png OK
if ( hr != S_OK ) return false;

return LoadImage2( target,pWICFactory, pStream, bmp );
}

bool D2DResource::LoadImage( ID2D1RenderTarget* target, LPCWSTR resource_section, int resource_id, ID2D1Bitmap** bmp )
{
HRESULT hr;
CComPtr pWICFactory;
CComPtr pStream;

hr= CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_ALL, __uuidof(IWICImagingFactory), (void**)&pWICFactory );
if ( hr != S_OK ) return false;

// load png from .rc
HMODULE hmodule = ::GetModuleHandle(NULL);
HRSRC hsrc = FindResource( hmodule, MAKEINTRESOURCE(resource_id), resource_section ); // resource_section:png
if ( hsrc == NULL ) return false;

DWORD len = SizeofResource(hmodule,hsrc);
HGLOBAL hg = LoadResource( hmodule, hsrc );
byte* d = (byte*)LockResource( hg );

hr = pWICFactory->CreateStream( &pStream );
if ( hr != S_OK ) return false;
hr = pStream->InitializeFromMemory( d, len ); // bmp,gif,jpg,png OK
if ( hr != S_OK ) return false;

return LoadImage2( target,pWICFactory, pStream, bmp );
}


bool D2DResource::LoadImage2( ID2D1RenderTarget* target,IWICImagingFactory* pWICFactory,IWICStream* pStream, ID2D1Bitmap** bmp )
{
_ASSERT( pWICFactory );

HRESULT hr;

CComPtr pDecoder;
CComPtr pSource;
CComPtr pConverter;

hr = pWICFactory->CreateDecoderFromStream( pStream, 0, WICDecodeMetadataCacheOnLoad, &pDecoder ); // jpeg,png:OK, bmp:88982f50のエラーになる, iconもエラー
if ( hr != S_OK ) return false;
hr = pDecoder->GetFrame(0, &pSource);
if ( hr != S_OK ) return false;

// Convert the image format to 32bppPBGRA
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = pWICFactory->CreateFormatConverter(&pConverter);
if ( hr != S_OK ) return false;
hr = pConverter->Initialize( pSource, GUID_WICPixelFormat32bppPBGRA,WICBitmapDitherTypeNone,NULL,0.f,WICBitmapPaletteTypeMedianCut);
if ( hr != S_OK ) return false;
hr = target->CreateBitmapFromWicBitmap(pConverter,NULL,bmp );

return ( hr == S_OK );
}