输入文件名,可以是bmp、png、jpg等格式文件
BOOL CreateBitmapFromFile(ID2D1HwndRenderTarget* renderTarget, const char* fileName)
{
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pSource = NULL;
IWICStream *pStream = NULL;
IWICFormatConverter *pConverter = NULL;
IWICImagingFactory* imageFactory = NULL;
//为了兼容win7、win10,这里采用CLSID_WICImagingFactory1
hr = CoCreateInstance(
CLSID_WICImagingFactory1,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
(LPVOID*)&imageFactory
);
if (FAILED(hr))
{
return FALSE;
}
//创建wic解码器
hr = imageFactory->CreateDecoderFromFilename(
CString(fileName),
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if (SUCCEEDED(hr))
{
// Create the initial frame.
hr = pDecoder->GetFrame(0, &pSource);
}
else
{
return FALSE;
}
if (SUCCEEDED(hr))
{
// Convert the image format to 32bppPBGRA
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = imageFactory->CreateFormatConverter(&pConverter);
}
if (!SUCCEEDED(hr))
{
return FALSE;
}
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
if (SUCCEEDED(hr))
{
// Create a Direct2D bitmap from the WIC bitmap.
//这里需要将wic位图转换成Direct2D位图
hr = renderTarget->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&mBitmap
);
if (FAILED(hr))
{
return FALSE;
}
}
SAFE_RELEASE(pDecoder);
SAFE_RELEASE(pSource);
SAFE_RELEASE(pStream);
SAFE_RELEASE(pConverter);
return TRUE;
}
由内存中的RGB数据创建
BOOL CreateBitmpFromMemory(ID2D1HwndRenderTarget* renderTarget, uint8_t* data, int w, int h, uint32_t pitch)
{
HRESULT hr = S_OK;
D2D1_SIZE_U size;
size.width = w;
size.height = h;
// Create a pixel format and initial its format
// and alphaMode fields.
//指定RGB格式
D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE
);
//设置属性
D2D1_BITMAP_PROPERTIES property;
property.pixelFormat = pixelFormat;
property.dpiX = 0;
property.dpiY = 0;
// Create a Direct2D bitmap from the memory.
hr = renderTarget->CreateBitmap(
size,
data,
pitch,
property,
&mBitmap
);
if (SUCCEEDED(hr))
{
return TRUE;
}
return FALSE;
}
从数据流中解码,数据可以是从网络上下载的jpeg格式数据流,或者其他格式的数据流,然后按照指定的尺寸缩放。
BOOL CreateBitmapFromDecodeMemory(ID2D1HwndRenderTarget* renderTarget,const uint8_t* data, size_t size, int dstW, int dstH)
{
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pSource = NULL;
IWICStream *pStream = NULL;
IWICFormatConverter *pConverter = NULL;
IWICBitmapScaler *pScaler = NULL;
IWICImagingFactory* imageFactory = NULL;
ID2D1Bitmap* bitmap = NULL;
hr = CoCreateInstance(
CLSID_WICImagingFactory1,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
(LPVOID*)&imageFactory
);
if (FAILED(hr))
{
return FALSE;
}
IStream* stream = SHCreateMemStream(data, size);
if (!stream)
{
return FALSE;
}
hr = imageFactory->CreateDecoderFromStream(
stream,
NULL,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if (SUCCEEDED(hr))
{
// Create the initial frame.
hr = pDecoder->GetFrame(0, &pSource);
}
else
{
return FALSE;
}
if (SUCCEEDED(hr))
{
// Convert the image format to 32bppPBGRA
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = imageFactory->CreateFormatConverter(&pConverter);
}
if (!SUCCEEDED(hr))
{
return FALSE;
}
if (dstW != 0 || dstH != 0)
{
UINT originalWidth, originalHeight;
hr = pSource->GetSize(&originalWidth, &originalHeight);
if (SUCCEEDED(hr))
{
if (dstW == 0)
{
FLOAT scalar = static_cast<FLOAT>(dstH) / static_cast<FLOAT>(originalHeight);
dstW = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
}
else if (dstH == 0)
{
FLOAT scalar = static_cast<FLOAT>(dstW) / static_cast<FLOAT>(originalWidth);
dstH = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
}
//创建wic缩放
hr = imageFactory->CreateBitmapScaler(&pScaler);
if (SUCCEEDED(hr))
{
hr = pScaler->Initialize(
pSource,
dstW,
dstH,
WICBitmapInterpolationModeCubic//最小立方插值,不知道底层如何实现,如果是cpu实现,追求效率,最好试用二次线性插值
);
}
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(
pScaler,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
}
}
else
{
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeCustom
);
}
if (SUCCEEDED(hr))
{
// Create a Direct2D bitmap from the WIC bitmap.
hr = renderTarget->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&bitmap
);
}
if (FAILED(hr))
{
SAFE_RELEASE(pDecoder);
SAFE_RELEASE(pSource);
SAFE_RELEASE(pStream);
SAFE_RELEASE(pConverter);
SAFE_RELEASE(pScaler);
return FALSE;
}
SAFE_RELEASE(pDecoder);
SAFE_RELEASE(pSource);
SAFE_RELEASE(pStream);
SAFE_RELEASE(pConverter);
SAFE_RELEASE(pScaler);
mBitmap = bitmap;
return TRUE;
}
常用的位图创建一般就这3中情况,可以根据需要增加其他处理。