Я пытаюсь применить размытие рамки к прозрачному изображению, и у меня появляется "темный ореол" по краям .
Джерри Хакстейбл имеет краткое упоминание о проблеме и очень хорошую демонстрацию, показывающую, что проблема возникает:
Но я, хоть убей, не могу понять, как " pre -множенная альфа "может решить проблему. А теперь очень простой пример. У меня есть изображение 3x3, содержащее один красный и один зеленый пиксели:
На самом деле оставшиеся пиксели прозрачны:
Теперь мы применим к изображению размытие 3x3 Box Blur. Для простоты мы Я рассчитываю только новое значение центрального пикселя. Принцип работы блочного размытия заключается в том, что поскольку у нас есть 9-позиционный квадрат (3x3, называемый ядром), мы берем 1/9 каждого пикселя в ядре и складываем его:
Итак
finalRed = 1/9 * red1 + 1/9 * red2 + 1/9 * red3+ ... + 1/9 * red9
finalGreen = 1/9*green1 + 1/9*green2 + 1/9*green3+ ... + 1/9*green9
finalBlue = 1/9* blue1 + 1/9* blue2 + 1/9* blue3+ ... + 1/9* blue9
finalAlpha = 1/9*alpha1 + 1/9*alpha2 + 1/9*alpha3+ ... + 1/9*alpha9
В этом очень упрощенном виде Например, вычисления становятся очень простыми:
finalRed = 1/9 * 255
finalGreen = 1/9 * 255
finalBlue = 0
finalAlpha = 1/9*255 + 1/9*255
Это дает мне окончательное значение цвета:
finalRed = 28
finalGreen = 28
finalBlue = 0
finalAlpha = 56 (22.2%)
Этот цвет слишком темный. Когда я выполняю размытие прямоугольника 3px на том же изображении 3x3 пикселя в Photoshop, я получаю то, что ожидал:
Что более четкое при отображении поверх белого:
На самом деле я выполняю размытие поля на растровом изображении, содержащем прозрачный текст, и текст приобретает характерную темноту по краям:
Я начинаю с растрового изображения GDI + в формате PixelFormat32bppARGB
Как использовать "предварительно умноженную альфа" при применении ядра свертки 3x3?
Любой ответ должен включать новый forumla, поскольку:
final = 1/9*(pixel1+pixel2+pixel3...+pixel9)
Я получаю неправильный ответ.
Изменить: Более простой пример:
Я выполню эта математика со значениями цвета и альфа в диапазоне 0..1:
Я собираюсь применить фильтр свертки размытия прямоугольника к среднему пикселю:
ARGB'
= 1/9 * (0,1,0,1) + 1/9 * (0,0,0,0) + 1/9 * (0,0,0,0) +
1/9 * (0,1,0,1) + 1/9 * (0,0,0,0) + 1/9 * (0,0,0,0) +
1/9 * (0,1,0,1) + 1/9 * (0,0,0,0) + 1/9 * (0,0,0,0);
= (0, 0.11, 0, 0.11) + (0,0,0,0) + (0,0,0,0) +
(0, 0.11, 0, 0.11) + (0,0,0,0) + (0,0,0,0) +
(0, 0.11, 0, 0.11) + (0,0,0,0) + (0,0,0,0)
= (0, 0.33, 0, 0.33)
Что дает довольно прозрачный темно-зеленый цвет.
Что это не то, что я ожидаю увидеть. И для сравнения Photoshop Box Blur:
Если я предполагаю, что (0, 0,33, 0, 0,33)
- это предварительно умноженная альфа, и не умножая ее, я получаю:
(0, 1, 0, 0.33)
Что выглядит правильно для моего непрозрачного примера; но я не знаю, что делать, когда начинаю задействовать частично прозрачные пиксели.