这是我用来加载 PNG 资源以使用 Direct2D 呈现它的代码(但它并不限制您仅使用 PNG 格式或仅使用 D2D):
/**
* Loads image from the specified resource and creates Direct2D bitmap object for that image.
*
* Parameters:
* >pszResourceName
* Image resource name.
* >pszResourceType
* Image resource type.
* >pImagingFactory
* Pointer to an instance of IWICImagingFactory object.
* >ppBitmapSource
* Receives loaded bitmap.
*
* Returns:
* Standard HRESULT code.
*/
HRESULT directx_toolkit::loadBitmapFromResource(
_In_z_ LPCTSTR pszResourceName,
_In_z_ LPCTSTR pszResourceType,
_In_ IWICImagingFactory* pImagingFactory,
_COM_Outptr_result_maybenull_ IWICFormatConverter** ppBitmapSource) const
{
ATLADD com_ptr<IWICFormatConverter> converter {};
HRESULT hr = E_FAIL;
HRSRC hResource = FindResource(ATL::_AtlBaseModule.GetResourceInstance(), pszResourceName, pszResourceType);
if (nullptr != hResource)
{
HGLOBAL hData = LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hResource);
if (nullptr != hData)
{
void* pData = LockResource(hData);
DWORD nSize = SizeofResource(ATL::_AtlBaseModule.GetResourceInstance(), hResource);
if (pData && nSize)
{
// Create a WIC stream to map onto the memory.
ATLADD com_ptr<IWICStream> stream {};
hr = pImagingFactory->CreateStream(stream.getAddressOf());
if (SUCCEEDED(hr))
{
hr = stream->InitializeFromMemory(reinterpret_cast<BYTE*> (pData), nSize);
if (SUCCEEDED(hr))
{
// Prepare decoder for the stream, the first image frame and conveter (to change image color
// format).
ATLADD com_ptr<IWICBitmapDecoder> decoder {};
hr = pImagingFactory->CreateDecoderFromStream(
stream.get(), nullptr, WICDecodeMetadataCacheOnLoad, decoder.getAddressOf());
if (SUCCEEDED(hr))
{
ATLADD com_ptr<IWICBitmapFrameDecode> frame {};
hr = decoder->GetFrame(0, frame.getAddressOf());
if (SUCCEEDED(hr))
{
hr = pImagingFactory->CreateFormatConverter(converter.getAddressOf());
if (SUCCEEDED(hr))
{
hr = converter->Initialize(
frame.get(),
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
nullptr,
0,
WICBitmapPaletteTypeMedianCut);
}
}
}
}
}
}
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
*ppBitmapSource = SUCCEEDED(hr) ? converter.detach() : nullptr;
return hr;
}
/**
* Loads image from the specified resource and creates Direct2D bitmap object for that image.
*
* Parameters:
* >pszResourceName
* Image resource name.
* >pszResourceType
* Image resource type.
* >pImagingFactory
* Pointer to an instance of IWICImagingFactory object.
* >pDC
* Direct2D context.
* >ppBitmap
* Receives loaded bitmap.
*
* Returns:
* Standard HRESULT code.
*
* Remarks:
* Since 'ID2D1DeviceContext::CreateBitmapFromWicBitmap' can't be called simultaneously from multiple threads, caller
* should synchronize access to the 'pDC'.
*/
HRESULT directx_toolkit::loadBitmapFromResource(
_In_z_ LPCTSTR pszResourceName,
_In_z_ LPCTSTR pszResourceType,
_In_ IWICImagingFactory* pImagingFactory,
_In_ ID2D1DeviceContext* pDC,
_COM_Outptr_result_maybenull_ ID2D1Bitmap1** ppBitmap) const
{
ATLADD com_ptr<ID2D1Bitmap1> bitmap {};
ATLADD com_ptr<IWICFormatConverter> converter {};
HRESULT hr = loadBitmapFromResource(pszResourceName, pszResourceType, pImagingFactory, converter.getAddressOf());
if (SUCCEEDED(hr))
{
hr = pDC->CreateBitmapFromWicBitmap(converter.get(), bitmap.getAddressOf());
}
*ppBitmap = SUCCEEDED(hr) ? bitmap.detach() : nullptr;
return hr;
}
(ATLADD com_ptr 是 ATL::CComPtr 的类似物)
毫无疑问,您可以使用 32bpp BMP 来获取具有透明蒙版的资源。