Подтвердить что ты не робот

Как рассчитать цвет RGB, указав альфа-смешение?

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

Например:

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

4b9b3361

Ответ 1

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

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. Повторите для остальных компонентов, и все готово.

Ответ 2

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

Если режим смешивания Normal, то это не слишком сложно:-)

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).

Ответ 3

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

    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));
    }

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