Преобразование цвета RGBA в RGB

Как преобразовать цветной кортеж RGBA, пример (96, 96, 96, 202), в соответствующий цветовой набор RGB?

Edit:

То, что я хочу, - получить RGB-значение, которое наиболее похоже на RGBA-кортеж визуально на белом фоне.

Ответ 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.

Ответ 2

hm... относительно

http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending

решение, предоставленное Андрасом Золтаном, должно быть слегка изменено на:

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)

Эта измененная версия отлично работает для меня, потому что в пред. версия rgba (0,0,0,0) с матовой rgb (ff, ff, ff) будет изменена на rgb (0,0,0).

Ответ 3

Это зависит от используемого вами цветового пространства. Если RGBA находится в предварительно умноженном цветовом пространстве и является полупрозрачным, вам нужно разделить альфу, чтобы получить правильный цвет RGB. Если цвет находится в неперемноженном цветовом пространстве, вы можете просто отказаться от альфа-канала.

Ответ 4

В моем случае я хотел преобразовать изображение RGBA в RGB, и следующее работало так, как ожидалось:

rgbImage = cv2.cvtColor(npimage, cv2.COLOR_RGBA2RGB)

Ответ 5

Вот удобная функция SASS в соответствии с ответами Андраса и Хрурабко.

@function rgba_blend($fore, $back) {
  $ored: ((1 - alpha($fore)) * red($back) ) + (alpha($fore) * red($fore));
  $ogreen: ((1 - alpha($fore)) * green($back) ) + (alpha($fore) * green($fore));
  $oblue: ((1 - alpha($fore)) * blue($back) ) + (alpha($fore) * blue($fore));
  @return rgb($ored, $ogreen, $oblue);
}

Использование:

$my_color: rgba(red, 0.5); // build a color with alpha for below

#a_div {
  background-color: rgba_blend($my_color, white);
}