Ручное альфа-смешивание пикселя RGBA с пикселем RGB

#python #pygame #rgb #rgba

Вопрос:

Я пытаюсь выполнить операцию альфа-наложения изображения RGBA (изображение переднего плана) на изображение RGB (фоновое изображение). Однако, делая это, я думаю, что, возможно, я выполняю неправильную операцию альфа-смешивания или делаю это неправильно. Например, пиксель моего RGB-изображения имеет сероватый цвет (127, 127, 127). Пиксель моего изображения RGBA для пикселя будет равен (0, 0, 255). После того, как я выполню операцию смешивания, окончательный цвет будет (127, 0, 255). Однако я думал, что это скорее смесь добавок и отличается от операции, которую я выполняю.

Чтобы узнать, как устанавливаются мои ценности, взгляните на это

 incPixelColor[0] = 0; (red)
incPixelColor[1] = 0; (green)
incPixelColor[2] = 255; (blue)
incPixelColor[3] = 255; (alpha)

currentPixelColor[0] = 127; (red)
currentPixelColor[1] = 127; (green)
currentPixelColor[2] = 127; (blue)
 

Чтобы узнать, как настроен мой расчет, взгляните на это

 float incAlpha = (currentPixelColor[3]/255.0f);

float red = ((float)incPixelColor[0]/255.0f * incAlpha)   ((float)currentPixelColor[0]/255.0f);
float green = ((float)incPixelColor[1]/255.0f * incAlpha)   ((float)currentPixelColor[1]/255.0f);
float blue = ((float)incPixelColor[2]/255.0f * incAlpha)   ((float)currentPixelColor[2]/255.0f);


currentPixelColor[0] = min(red * 255, 255.0f);
currentPixelColor[1] = min(green * 255, 255.0f);
currentPixelColor[2] = min(blue * 255, 255.0f);
 

Для пикселей без альфы я бы хотел, чтобы значение было (0, 0, 255), затем для изображений с альфой я бы хотел, чтобы оно сливалось. В конце описанной выше операции это будет (127, 127, 255). Должен ли я проверить, есть ли альфа для каждого пикселя, и если да, то выполнить смешивание или есть другой способ сделать это?

Комментарии:

1. Вы делаете смешивание добавок. Рассмотрим линейное смешивание следующим образом: y = (x0 * w) (x1 * (1-w))

2. Это много 255 масштабирования вперед и назад. В этом не должно быть необходимости, если ваши операции поддерживают нормализацию.

Ответ №1:

Типичная «избыточная» смесь выполняется следующим образом:

 outputRed = (foregroundRed * foregroundAlpha)   (backgroundRed * (1.0 - foregroundAlpha));
 

А затем повторяем для синего и зеленого каналов. Сделайте это для каждого пикселя.

Комментарии:

1. Возможно, я ошибаюсь, но разве это не то, что я уже делаю?

2. Нет, то, что вы делаете, — это outputRed = (foreRed * foreAlpha) backgroundRed. Вам нужно умножить фоновое значение на (1,0 — foreAlpha).

3. Извините, что так поздно, но что происходит с альфа-выходным альфа-каналом, если как пиксели назначения, так и исходные пиксели прозрачны?

4. В конечном итоге это тоже становится прозрачным. Поэтому, если у вас есть исходный пиксель с покрытием 0% (альфа), он не должен вносить вклад в вывод. Если вы наложите это на пиксель с покрытием 0%, фон также не должен влиять на результат. Таким образом, результатом будет RGBA = (0,0,0,0). Он будет, так сказать, «прозрачно-черным». Если вы наложите результат на что-то непрозрачное, вы увидите все, на что вы его наложили.

5. Предполагает ли это, что foregroundAlpha находится в диапазоне 0-255 или 0-1?

Ответ №2:

Похоже, что вы пропустили (1-Альфа) множитель для фона (текущий пиксельный цвет)