Direct2D — Как сделать гамма-корректную прозрачность (альфа) с растровыми изображениями

Я рисую растровые изображения в Direct2D. Растровые изображения используют прозрачность (альфа-канал).

Смешивание выглядит неправильно.

В качестве теста я загрузил чистое черное изображение PNG с прозрачностью 50% и нарисовал его на белом фоне. Результатом являются пиксели со значениями красного, зеленого и синего 127 (0x7F7F7F). Это говорит о том, что смесь Direct2D игнорирует гамму и обрабатывает значения цвета, как если бы они были линейными.

(Растровые изображения используют обычное цветовое пространство sRGB и имеют размер 32 бита на пиксель, по 8 бит для красного, зеленого, синего и альфа-канала). Они загружаются в формате GUID_WICPixelFormat32bppPBGRA.

В sRGB смесь на полпути между черным и белым составляет 186 (0xBABABA). Это идеальный результат, который я хочу.

Может ли Direct2D отображать прозрачность с учетом гаммы? Как бы я это сделал? Любая помощь приветствуется.

Direct2D против гамма-правильной смеси

3

Решение

Смешивание правильно выполняется в линейном цветовом пространстве, поэтому процесс смешивания пикселей sRGB должен быть

  1. преобразовать в линейный
  2. смесь
  3. преобразовать обратно в sRGB.

Обратите внимание, что с черными или белыми пикселями шаги (1) и (3) не допускаются и могут быть пропущены.

Увидеть обработка альфа-канала раздел спецификации PNG. В частности, обратите внимание на это:

Уравнение для вычисления значения составной выборки

output = alpha * foreground + (1-alpha) * background

где альфа-значение и входные и выходные значения выборки
выражается в виде дроби в диапазоне от 0 до 1. Это вычисление должно быть
выполняется с выборками интенсивности (не с гамма-кодированием)

Раздел содержит пример кода C для обработки альфа-канала.

В то время, когда был задан этот вопрос, цели HWND Render (рисование на экране) не поддерживали линейные пиксельные форматы; однако цели Direct-2D HwndRender теперь заменены интерфейсом ID2D1DeviceContext. Они созданы через IDXGIFactory2::CreateSwapChainForHwnd() и поддерживает больше форматов пикселей, таких как DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, который автоматически выполняет правильные преобразования цветового пространства при смешивании (информация предоставлена ​​@Jeff McClintock).

1

Другие решения

Direct-2D 1.0 HwndRenderTarget выполняет расчеты смешивания непосредственно для значений пикселей. Это приводит к ошибкам при компоновке стандартных изображений sRGB с использованием альфа-канала. Ошибка заключается в том, что Direct 2D обрабатывает значения интенсивности со сжатием гамма-излучения как если бы они были линейными значениями интенсивности.

Игнорирование гаммы приводит к низкому качеству компоновки, сглаживанию геометрии, изменению размера изображения и визуализации текста.

Существует обходной путь, который заключается в том, чтобы «предварительно деформировать» альфа-значения растрового изображения, чтобы компенсировать ошибки, вносимые расчетом смешивания.

пример:
Изображение слева — правильное наложение, выполняя смешивание в линейном цветовом пространстве, центральное изображение — Direct 2D (слишком темная и контрастная тень), изображение справа — Direct2D после предварительной деформации альфа-канала.

Direct 2D рендеринг альфа-смесей в темные и'contrasty'

увидеть: https://bel.fi/alankila/lcd/alpcor.html

ОБНОВЛЕНИЕ !: Новые версии Direct-2D (1.1) Поддерживает обратные буферы SRGB, которые выполняют смешивание правильно. Используйте IDXGIFactory2 :: CreateSwapChainForHwnd (), чтобы использовать улучшенные параметры глубины цвета.

0

По вопросам рекламы [email protected]