Какой должна быть конструкция BITMAPINFOHEADER, если biCompression равен BI_PNG? - PullRequest
0 голосов
/ 25 февраля 2020

Мне нужны предложения о конструкции BITMAPINFOHEADER для изображений PNG. Этот заголовок информации о растровом изображении будет использоваться для сохранения буфера в формате PNG с использованием GdiPlus :: Bitmap. Мой буфер изображений - это 32-битное изображение PNG.

Я сделал следующее, но GdiPlus :: Bitmap :: GetLastStatus () говорит «Неверный параметр», и я не могу сохранить буфер в формате файла png.

void CreateBitmapInfo(long lWidth, long lHeight, bool bColor, CComHeapPtr<BITMAPINFO>& apBitmapInfo)
{
    const auto bitCount = 32;
    const auto colorUsed = 2;
    long lBitmapInfoSize = sizeof(BITMAPINFOHEADER);
    if (!bColor)
        lBitmapInfoSize += colorUsed * sizeof(RGBQUAD);

    TRY_CONDITION(apBitmapInfo.AllocateBytes(lBitmapInfoSize));

    ::memset(apBitmapInfo, 0, lBitmapInfoSize);

    apBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    apBitmapInfo->bmiHeader.biWidth = lWidth;
    apBitmapInfo->bmiHeader.biHeight = lHeight;
    apBitmapInfo->bmiHeader.biPlanes = 1;
    apBitmapInfo->bmiHeader.biBitCount = bitCount;
    apBitmapInfo->bmiHeader.biCompression = BI_PNG;
    apBitmapInfo->bmiHeader.biSizeImage = gsl::narrow_cast<uint32_t>(((lWidth + 7) & 0xFFFFFFF8) * lHeight / 8); // zero for BI_RGB
    apBitmapInfo->bmiHeader.biXPelsPerMeter = 0;
    apBitmapInfo->bmiHeader.biYPelsPerMeter = 0;
    apBitmapInfo->bmiHeader.biClrUsed = bColor ? 0 : colorUsed;
    apBitmapInfo->bmiHeader.biClrImportant = 0;

    if (!bColor)
    {
        // create a gray scale color table
        for (int i = 0; i < colorUsed; i++)
        {
            RGBQUAD& rgb = *(apBitmapInfo->bmiColors + i);
            rgb.rgbRed = rgb.rgbGreen = rgb.rgbBlue = gsl::narrow_cast<BYTE>(i);
        }
    }
}
...