Ответ 1
Я поддержал ответ Йоханнеса, потому что он прав насчет этого.
* Было высказано несколько замечаний о том, что мой первоначальный ответ был неправильным. Он работал, если альфа-значения были инвертированы из нормального. Однако по определению это не будет работать в большинстве случаев. Поэтому я обновил приведенную ниже формулу, чтобы быть правильным для нормального случая. Это заканчивается равным @hkurabko ниже:
Более конкретный ответ, однако, включает значение альфа в фактический результат цвета на основе непрозрачного цвета фона (или "матового", как он упоминается).
Существует алгоритм для этого (из this wikipedia link):
- Нормализовать значения RGBA, чтобы они находились между 0 и 1 - просто разделите каждое значение на 255, чтобы сделать это. Мы назовем результат
Source
. - Нормализовать также матовый цвет (черный, белый - любой). Мы будем называть результат
BGColor
Примечание - если цвет фона также прозрачен, вам придется сначала перенести процесс для этого (опять же, выбрав матовый), чтобы получить исходный RGB для этой операции. -
Теперь преобразование определяется как (в полном коде psuedo здесь!):
Source => Target = (BGColor + Source) = Target.R = ((1 - Source.A) * BGColor.R) + (Source.A * Source.R) Target.G = ((1 - Source.A) * BGColor.G) + (Source.A * Source.G) Target.B = ((1 - Source.A) * BGColor.B) + (Source.A * Source.B)
Чтобы получить окончательные значения 0-255 для Target
, вы просто умножаете все нормализованные значения на 255, чтобы убедиться, что вы закрываете 255, если какое-либо из комбинированных значений превышает 1.0 (это чрезмерное воздействие и есть более сложные алгоритмы, связанные с этим, которые включают обработку всего изображения и т.д.).
EDIT: В вашем вопросе вы сказали, что хотите белый фон - в этом случае просто исправьте BGColor до 255,255,255.