Кой CGImageAlphaInfo трябва да използваме?

Рел= "noreferrer">Ръководството за програмиране на Quartz 2D определя наличността на различните алфа режими на съхранение:

въведете описание на изображението тук

Кои трябва да използваме за RGB контексти и защо?

За непрозрачни контексти, kCGImageAlphaPremultipliedFirst или kCGImageAlphaPremultipliedLast?

За непрозрачни контексти, kCGImageAlphaNoneSkipFirst или kCGImageAlphaNoneSkipLast?

Изборът на стойност влияе ли на ефективността?

Обикновено виждам kCGImageAlphaPremultipliedFirst за непрозрачни и kCGImageAlphaNoneSkipFirst за непрозрачни контексти. Някои твърдят, че те се представят по-добре, но не съм виждал твърди доказателства или документация за това.

Бързо търсене в GitHub показва, че разработчиците предпочитат kCGImageAlphaPremultipliedFirst пред kCGImageAlphaPremultipliedLast и kCGImageAlphaNoneSkipLast пред kCGImageAlphaNoneSkipFirst. За съжаление, това е малко повече от анекдотични доказателства.


person hpique    schedule 18.05.2014    source източник
comment
Обзалагам се, че най-добрият вариант е различен в зависимост от наличния GPU хардуер. Тъй като аз лично нямам достъп до всички ~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 (True color format), където алфа байтът се намира в последния байт, описващ пиксела. - 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 Filters - ще откриете, че много филтри, особено CIColorMatrix, очакват RGBA (True color) формат, не че няма да можете да използвате другите формати, но ще трябва да ги конвертирате първо .... - person Paulo; 26.05.2014
comment
Здравей Пауло. ARGB обикновено се използва в iOS активи, въпреки че не знам точно защо. Мисля, че отговорът ви трябва да бъде коментар, тъй като е по-скоро обяснение на цветовите формати, отколкото опит за отговор на въпроса(ите) ми. - person hpique; 26.05.2014
comment
Всъщност вашият коментар относно основните филтри за изображения е по-подходящ за въпроса, отколкото действителния ви отговор. - person hpique; 26.05.2014
comment
UIColor обикновено са RGBA с изключение на UIColor Black или white, които са монотонни. Имам приложение, което работи с много изображения и повечето от функциите очакват RGBA. по някакъв начин в това голямо приложение. Никога не ми се е налагало да се занимавам с нито един от ARBG обектите. Както и да е, препозовах се на статията, защото True Color 32bit 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 bpc), а не 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