Просто в теории: как альфа-компонент предварительно умножается на другие компоненты PNG в iPhone OS, и как он может быть правильно умножен? - PullRequest
2 голосов
/ 16 мая 2009

На самом деле, я думал, что будет легкий способ достичь этого. Что мне нужно, так это чистая альфа-информация. Для тестирования у меня есть PNG размером 50 x 55 пикселей, где на каждом краю прямоугольник 5x5 пикселей полностью прозрачен. В этих областях альфа должна быть 0. В любом другом месте она должна быть 255. Я убедился, что мой PNG создан правильно, и он также выглядит правильно.

Пожалуйста, скажите мне, если это теоретически правильно: Я создал CGImageRef, который имеет только альфа-канал и ничего больше. Это делается с помощью CGBitmapContextCreate и kCGImageAlphaOnly в качестве параметра. CGBitmapContextGetBitsPerPixel (context) возвращает мне 1, так что это указывает на то, что у меня действительно только один компонент на пиксель: желаемое альфа-значение. Я читал, что CGBitmapContextCreate будет обрабатывать все преобразования из данного изображения в новый созданный контекст. Мое изображение ранее было PNG-24 с прозрачностью, но pngcrunch из Xcode, похоже, как-то их конвертирует.

Итак, просто в теории: есть ли у меня хоть какой-то шанс добраться до правильной, неумноженной альфы на этом этапе? Кажется, что значения, которые я получаю, почти совпадают, но в большом прозрачном квадрате 5x5 я получаю значения, такие как 19, 197, 210, 0, 0, 0, 98 и так далее. Если бы они были правдой, я бы увидел что-то на картинке. Само изображение сплошное синее.

Ответы [ 3 ]

7 голосов
/ 16 мая 2009

Преумножение не влияет на альфа-канал, оно влияет на цветовые каналы.

Формула для растрового композитинга (наложение одного растрового изображения поверх другого):

dst.r = src.r * src.a + dst.r * (1.0 - src.a);
dst.g = src.g * src.a + dst.g * (1.0 - src.a);
dst.b = src.b * src.a + dst.b * (1.0 - src.a);

Предварительное умножение обрезает первое выражение умножения:

dst.r = src.r′ + dst.r * (1.0 - src.a);
dst.g = src.g′ + dst.g * (1.0 - src.a);
dst.b = src.b′ + dst.b * (1.0 - src.a);

Это работает, потому что исходные компоненты цвета уже умножены на альфа-компонент - отсюда и название «предварительно умножено». Теперь не нужно их умножать, потому что у него уже есть результаты.

неумноженная альфа

Сам альфа-компонент никогда не умножается заранее: на что бы вы умножили его? Компоненты color предварительно умножаются на альфа .

5 голосов
/ 16 мая 2009

Поскольку предварительное умножение значений цвета является простым как:

r = (r * a) / 255;
g = (g * a) / 255;
b = (b * a) / 255;

Получение обратного будет:

if (a > 0) {
    r = (r * 255) / a;
    g = (g * 255) / a;
    b = (b * 255) / a;
}
0 голосов
/ 26 марта 2013

Эта формулировка не верна. Цель состоит в том, чтобы найти мультиплексированные (r, g, b), которые в последствии приводят к тем же мультиплексированным значениям (однако невозможно найти исходные значения r, g, b.

Однако с формулой выше мы находим для примера

alpha = 100
r_premulti = 1

реконструированный г = 2;

Позднее, если этот r снова мультиплексируется, мы находим 2 * 100/255 = 0, но вместо этого мы хотели r_premulti == 1 !!

Для правильной формы нужно округлить . Пример для r-компонента:

reconstruced r = ceiling(r_premulti * 255 / alpha)
...