Какой CGImageAlphaInfo мы должны использовать?

Отн. "noreferrer">Руководство по программированию Quartz 2D определяет доступность различных режимов альфа-хранилища:

введите здесь описание изображения

Какие из них следует использовать для контекстов RGB и почему?

Для непрозрачных контекстов kCGImageAlphaPremultipliedFirst или kCGImageAlphaPremultipliedLast?

Для непрозрачных контекстов kCGImageAlphaNoneSkipFirst или kCGImageAlphaNoneSkipLast?

Влияет ли выбор значения на производительность?

Обычно я вижу kCGImageAlphaPremultipliedFirst для непрозрачных контекстов и kCGImageAlphaNoneSkipFirst для непрозрачных контекстов. Некоторые утверждают, что они работают лучше, но я не видел никаких веских доказательств или документации по этому поводу.

Быстрый поиск на GitHub показывает, что разработчики предпочитают kCGImageAlphaPremultipliedFirst kCGImageAlphaPremultipliedLast и kCGImageAlphaNoneSkipLast kCGImageAlphaNoneSkipFirst. К сожалению, это не более чем неофициальные свидетельства.


person hpique    schedule 18.05.2014    source источник
comment
Могу поспорить, что лучший вариант зависит от того, какое аппаратное обеспечение графического процессора доступно. Поскольку у меня лично нет доступа ко всем примерно 50 различным графическим процессорам, которые Apple поставила за последние несколько лет, я не могу помочь вам с какими-либо данными о том, что лучше. Напишите приложение для стендового тестирования его производительности, а также профилируйте точный цветовой вывод каждого метода, а затем запустите его на любом доступном оборудовании.   -  person Abhi Beckert    schedule 21.05.2014
comment
различные параметры определяют, как пиксельные данные вычисляются и представляются внутри... например, при построении изображений из необработанных пиксельных данных (подача c-массивов) это имеет огромное значение, если вы, например, выберете неправильное альфа-представление.   -  person Volker    schedule 21.05.2014
comment
@AbhiBeckert Это тоже мое внутреннее чувство, но было бы неплохо получить какое-то подтверждение или консенсус по этому поводу. Бьюсь об заклад, что большинство разработчиков просто копируют CGBitmapContextCreate код без особых усилий, если они используют правильную растровую информацию.   -  person hpique    schedule 21.05.2014
comment
@Volker Имеет смысл сделать так, чтобы информация о растровом изображении соответствовала формату необработанных данных, но влияет ли информация о растровом изображении также на производительность отрисовки? Возможно, усиление при создании (которое можно сделать в фоновом режиме) теряется во время отрисовки (основной поток).   -  person hpique    schedule 21.05.2014
comment
Я предполагаю, что это повлияет на производительность и точность. Видеокарты, особенно видеокарты потребительского класса, не всегда передают точные цвета. Это одна из причин, по которой они намного быстрее, чем выполнение тех же операций на ЦП. Они просто должны быть достаточно хорошими, чтобы пользователь не заметил никаких неточностей. Если вам не все равно, то вам нужно проверить это.   -  person Abhi Beckert    schedule 21.05.2014
comment
никогда не оптимизируйте преждевременно - вы видите какие-либо проблемы с производительностью, а затем создаете версии, используя ту или другую, и проводите тесты. Я честно поиграл с различными форматами и не выявил проблем, которые увидят конечные пользователи...   -  person Volker    schedule 21.05.2014


Ответы (4)


Подтверждено инженером Apple на WWDC 2014, что мы должны использовать kCGImageAlphaPremultipliedFirst или kCGImageAlphaNoneSkipFirst, и что это влияет на производительность.

person hpique    schedule 05.06.2014
comment
Если вы читаете это из будущего, отнеситесь к этому с недоверием. Может изменилось! - person hpique; 06.06.2014

Наиболее широко используется формат RGBA (формат истинного цвета), в котором альфа-байт расположен в последнем байте, описывающем пиксель. - kCGImageAlphaPremultipliedLast (32 бита). Не все форматы одинаково поддерживаются всеми устройствами. Просто наблюдение, но все изображения png и jpeg, которые я обрабатывал, загруженные из Интернета, имеют формат RGBA (или превращаются в него, когда я конвертирую PNG в UIImage) - я никогда не сталкивался файл в формате ARGB в дикой природе, хотя я знаю, что это возможно.

Различные форматы влияют на размер файла изображения и качество цвета (если вы не знали) и качество изображения, 8-битные форматы являются черно-белыми (оттенки серого). Обсуждение всего этого можно найти здесь: http://en.wikipedia.org/wiki/Color_depth

person Paulo    schedule 26.05.2014
comment
Еще одна вещь — если вы используете фильтры Core Image — вы обнаружите, что многие фильтры, особенно CIColorMatrix, ожидают формат RGBA (истинный цвет), а не то, что вы не сможете использовать другие форматы, но вам нужно будет их преобразовать. первый .... - person Paulo; 26.05.2014
comment
Привет, Пауло. ARGB обычно используется в активах iOS, хотя я точно не знаю, почему. Я думаю, что ваш ответ должен быть комментарием, так как это скорее объяснение цветовых форматов, чем попытка ответить на мой вопрос (вопросы). - person hpique; 26.05.2014
comment
Фактически, ваш комментарий о Core Image Filters больше относится к вопросу, чем ваш фактический ответ. - person hpique; 26.05.2014
comment
UIColor обычно представляет собой RGBA, за исключением UIColor Black или white, которые являются монотонными. У меня есть приложение, которое работает с большим количеством изображений, и большинство функций требуют RGBA. как-то в этом большом приложении. Мне никогда не приходилось иметь дело ни с одним из объектов ARBG. В любом случае, я сослался на эту статью, потому что True Color 32-битный RGBA общепризнан и является типичным выходом Photoshop и другого широко используемого программного обеспечения для обработки изображений, использование RGBA обеспечивает совместимость с широким спектром других приложений, особенно если изображение, которое вы создаете, должно использоваться взаимозаменяемо в другие платформы. - person Paulo; 27.05.2014

Для лучшей производительности ваши байты на строку и данные должны быть выровнены по кратным 16 байтам.

бит на компонент: количество битов, используемых для каждого компонента цвета. Для 16-битного RGBA компоненты 16/4 = 4.

бит на пиксель: не менее бит на компонент * количество компонентов

байт на строку: ((бит на компонент * количество компонентов + 7)/8) * ширина

Из CGBitmapContext.h:

Количество битов для каждого компонента пикселя определяется параметром «bitsPerComponent». Количество байтов на пиксель равно «(bitsPerComponent * количество компонентов + 7)/8». Каждая строка растрового изображения состоит из bytesPerRow' bytes, which must be at leastwidth * байтов на пиксель' байтов; кроме того, `bytesPerRow' должен быть целым числом, кратным количеству байтов на пиксель.

Если у вас есть байты на строку с заданным форматом пикселей и цветовым пространством, если оно делится на 16, вы должны быть в хорошей форме. Если вы НЕ правильно выровнены, Quartz выполнит некоторые из этих оптимизаций за вас, что повлечет за собой накладные расходы. Для получения дополнительных очков вы также можете попытаться оптимизировать количество байтов на строку, чтобы они соответствовали строке кэша L2 в целевой архитектуре.

Это подробно описано в Руководство по программированию Quartz 2D, а также документацию для CGImage. Существует также вопрос, который может иметь значение.

Все это говорит о том, что лучше всего попробовать разные вещи и профилировать в инструментах.

person quellish    schedule 28.05.2014
comment
Байты на строку — это (байты на пиксель) * ширина, а не (биты на компонент) * (количество компонентов) * ширина: пиксели не могут шагать на несколько единиц. Если вы используете 16-битный RGB, один пиксель равен 16 битам, независимо от того, какой бит остается неиспользованным. Кроме того, я думаю, что Quartz поддерживает только RGB более 16 бит (с 5 битами на канал), а не RGBA. - person zneak; 28.05.2014
comment
Из CGBitmapContext.h: количество байтов на пиксель равно (bitsPerComponent * количество компонентов + 7)/8'. Умножьте это на количество пикселей в строке (ширину). kCGImageAlphaLast — это пример RGBA без предварительного умножения. kCGImageAlphaPremultipliedLast будет RGBA с предварительным умножением. - person quellish; 28.05.2014

Я использую kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big, и он отлично работает.

person Michał Ziobro    schedule 25.09.2016