При рисовании изображений PixelFormat32bppPARGB с помощью GDI+ вместо предварительно умноженной используется обычная формула

Вот некоторый минимальный код, чтобы показать проблему:

static const int MAX_WIDTH = 320;
static const int MAX_HEIGHT = 320;

Gdiplus::Bitmap foregroundImg(MAX_WIDTH,MAX_HEIGHT,PixelFormat32bppPARGB);
{
    Gdiplus::Graphics g(&foregroundImg);
    g.Clear(Gdiplus::Color(10,255,255,255));
}

Gdiplus::Bitmap softwareBitmap(MAX_WIDTH,MAX_HEIGHT,PixelFormat32bppPARGB);
Gdiplus::Graphics g(&softwareBitmap);
g.SetCompositingMode(Gdiplus::CompositingModeSourceOver);
g.SetCompositingQuality(Gdiplus::CompositingQualityDefault);

g.Clear(Gdiplus::Color(255,0,0,0));

g.DrawImage(foregroundImg,0,0);

CLSID encoder;
GetEncoderClsid(L"image/png",&encoder);
softwareBitmap.Save(L"d:\\image.png",&encoder);

В результате я получаю изображение, заполненное значениями RGB, равными 10, Похоже, GDI+ использует традиционный алгоритм:

255 * (10/255) + 0 * (1-10 / 255) == 10.

Но я ожидаю, что будет использоваться предварительно умноженный алгоритм (потому что на переднем плане изображение предварительно умножено PixelFormat32bppPARGB формат):

255 + 0 * (1-10 / 255) == 255

Итак, мой вопрос, почему GDI+ использует обычную формулу, когда изображение находится в предварительно умноженном альфа-формате? И есть ли обходной путь, чтобы заставить GDI+ использовать предварительно умноженный альфа-алгоритм?

1 ответ

Решение

Формат изображения переднего плана не имеет значения (учитывая, что оно имеет альфа-канал), потому что вы устанавливаете его в Gdiplus::Color. Цветовые значения определены как неумноженные, поэтому gdiplus умножает компоненты на альфа-значение, когда очищает изображение переднего плана. Альтернативой было бы, чтобы значения Color имели различное значение в зависимости от формата цели рендеринга, и в этом заключается безумие.

Возможно, вы сможете сделать то, что намереваетесь, установив биты исходного изображения напрямую, или вы не сможете этого сделать. Компоненты со значениями, превышающими 100%, на самом деле недопустимы в модели рендеринга gdiplus, поэтому я не удивлюсь, если они будут ограничены во время рендеринга. Если вы действительно хотите этот уровень контроля над рендерингом, вам придется заблокировать биты растрового изображения и сделать это самостоятельно.

Другие вопросы по тегам