我想使用
BITMAPINFO
结构来定义 32 位 png 图像的 DIB,这样我就可以使用 StretchDIBits
将图像发送到打印机进行打印。
我尝试了以下代码:
HDC memDC = CreateCompatibleDC(hdcPrinter);
BITMAPINFO bmi = { 0 };
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -static_cast<int>(height);
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
void* bits = NULL;
HBITMAP dib = CreateDIBSection(memDC, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
//...
但我不确定这是否会丢失图像的 Alpha 通道。
您的
BITMAPINFO
结构构造正确。作为旁注,您可以使用 Windows Imaging Component 进行转换。
HRESULT ConvertBitmapSourceTo32BPPHBITMAP(IWICBitmapSource *pBitmapSource,
IWICImagingFactory *pImagingFactory,
HBITMAP *phbmp)
{
*phbmp = NULL;
IWICBitmapSource *pBitmapSourceConverted = NULL;
WICPixelFormatGUID guidPixelFormatSource;
HRESULT hr = pBitmapSource->GetPixelFormat(&guidPixelFormatSource);
if (SUCCEEDED(hr) && (guidPixelFormatSource != GUID_WICPixelFormat32bppBGRA))
{
IWICFormatConverter *pFormatConverter;
hr = pImagingFactory->CreateFormatConverter(&pFormatConverter);
if (SUCCEEDED(hr))
{
// Create the appropriate pixel format converter
hr = pFormatConverter->Initialize(pBitmapSource, GUID_WICPixelFormat32bppBGRA, WICBitmapDitherTypeNone, NULL, 0, WICBitmapPaletteTypeCustom);
if (SUCCEEDED(hr))
{
hr = pFormatConverter->QueryInterface(&pBitmapSourceConverted);
}
pFormatConverter->Release();
}
}
else
{
hr = pBitmapSource->QueryInterface(&pBitmapSourceConverted); // No conversion necessary
}
if (SUCCEEDED(hr))
{
UINT nWidth, nHeight;
hr = pBitmapSourceConverted->GetSize(&nWidth, &nHeight);
if (SUCCEEDED(hr))
{
BITMAPINFO bmi = {};
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth = nWidth;
bmi.bmiHeader.biHeight = -static_cast<LONG>(nHeight);
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
BYTE *pBits;
HBITMAP hbmp = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, reinterpret_cast<void **>(&pBits), NULL, 0);
hr = hbmp ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
WICRect rect = {0, 0, nWidth, nHeight};
// Convert the pixels and store them in the HBITMAP. Note: the name of the function is a little
// misleading - we're not doing any extraneous copying here. CopyPixels is actually converting the
// image into the given buffer.
hr = pBitmapSourceConverted->CopyPixels(&rect, nWidth * 4, nWidth * nHeight * 4, pBits);
if (SUCCEEDED(hr))
{
*phbmp = hbmp;
}
else
{
DeleteObject(hbmp);
}
}
}
pBitmapSourceConverted->Release();
}
return hr;
}