Как рассчитать цвет RGB, указав величину альфа-смешения? - PullRequest
53 голосов
/ 14 апреля 2009

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

Например:

Результирующий цвет пикселя составляет 240 247 249, но я знаю, что исходный цвет имел непрозрачность 10% и был поверх белого (255 255 255) фона. Как рассчитать исходные значения RGB?

Ответы [ 3 ]

89 голосов
/ 14 апреля 2009

Стандартное уравнение смешивания:

out = alpha * new + (1 - alpha) * old

Где out, new и old - цвета RGB, а alpha - число с плавающей запятой в диапазоне [0,1].

Итак, у вас есть (для красного):

240 = 0.1 * newR + 0.9 * 255

Решая для newR, получим:

newR = (240 - 0.9 * 255) / 0.1

, что соответствует 105. Повторите для других компонентов, и все готово.

31 голосов
/ 14 апреля 2009

Мне просто интересно, откуда вы знаете его альфа, а не его r, g, b ... Если используемый режим смешивания не является в каждом случае нормальным, вы не сможете рассчитать исходное значение. И даже если все идеально, вы сможете только приблизиться, так как некоторое округление, вероятно, уже имело место при переходе от оригинала к результату. Кроме того, вам, скорее всего, придется округлять при переходе от результата к оригиналу.

Если режим смешивания Нормальный, то это не так уж сложно :-)

opacity*original + (1-opacity)*background = resulting pixel

original R = (resulting R - ((1-opacity)*background R)) / opacity.
original G = (resulting G - ((1-opacity)*background G)) / opacity.
original B = (resulting B - ((1-opacity)*background B)) / opacity.

при непрозрачности (alpha/100).

4 голосов
/ 18 марта 2016

Следующий псевдокод решит вашу проблему:

    CalculateSolidColorFromTransparentColor(Color color, Color background)
    {
        alpha = color.A / 255;
        oneminusalpha = 1 - alpha;

        newR = ((color.R * alpha) + (oneminusalpha * background.R));
        newG = ((color.G * alpha) + (oneminusalpha * background.G));
        newB = ((color.B * alpha) + (oneminusalpha * background.B));
    }

Обратите внимание, что входной цвет и фон имеют значения, выраженные в [0..255]

...