Альфа-композитинг с фиксированной точкой (0xff не равен 1,0)C++

Программы на C++. Форум разработчиков
Anonymous
Альфа-композитинг с фиксированной точкой (0xff не равен 1,0)

Сообщение Anonymous »

Я пишу код на C, который выполняет альфа-компоновку с использованием целочисленной математики (с фиксированной точкой), и столкнулся с проблемой: 0xff не совсем равен 1,0. Это особенно проблематично в альфа-канале. Например (0xff * 0xff) >> 8 равно 0xfe. Итак, если у вас есть белый пиксель с альфа-0xff и RGB 0xff, и вы пытаетесь предварительно умножить альфа-канал на цветовые каналы, вы получите 0xfe в каналах RGB, поэтому у вас больше нет белого цвета.
Вот несколько примеров функций, которые выполняют предварительное умножение альфа, а затем альфа-композицию с предварительно умноженным альфа, обе из которых имеют некоторый вариант этой проблемы. Они предназначены для RGBA/BGRA с прямым порядком байтов, давайте пока проигнорируем проблемы с порядком байтов:

Код: Выделить всё

unsigned premultiply_alpha(unsigned color)
{
unsigned alpha = ((color>>24) & 0xff);
unsigned rb = color & 0xff00ffU;
unsigned g  = color & 0x00ff00U;

rb = (rb * alpha) >> 8;
g  = (g  * alpha) >> 8;

return (color & 0xff000000) | (rb & 0xff00ff) | (g & 0x00ff00);
}

Код: Выделить всё

unsigned rgb_blend(unsigned background, unsigned color)
{
unsigned alpha = color>>24;
unsigned rb = background & 0xff00ffU;
unsigned  g = background & 0x00ff00U;
rb = (color & 0xff00ff) + ((0xff - alpha) * rb >> 8);
g  = (color & 0x00ff00) + ((0xff - alpha) * g  >> 8);

unsigned dest_alpha = background>>24;
dest_alpha = alpha + dest_alpha - ((alpha*dest_alpha) >> 8);
dest_alpha = dest_alpha < 255 ? dest_alpha : 255;

return  (dest_alpha 

Подробнее здесь: [url]https://stackoverflow.com/questions/78686806/alpha-compositing-in-fixed-point-0xff-is-not-1-0[/url]

Вернуться в «C++»