Вот несколько примеров функций, которые выполняют предварительное умножение альфа, а затем альфа-композицию с предварительно умноженным альфа, обе из которых имеют некоторый вариант этой проблемы. Они предназначены для 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]