Кажется, что CGContextDrawImage (CGContextRef, CGRect, CGImageRef) выполняет гораздо больше при рисовании CGImage, который был создан CoreGraphics (то есть с CGBitmapContextCreateImage), чем при рисовании CGImage, который поддерживает UIImage.Посмотрите этот метод тестирования:
-(void)showStrangePerformanceOfCGContextDrawImage
{
///Setup : Load an image and start a context:
UIImage *theImage = [UIImage imageNamed:@"reallyBigImage.png"];
UIGraphicsBeginImageContext(theImage.size);
CGContextRef ctxt = UIGraphicsGetCurrentContext();
CGRect imgRec = CGRectMake(0, 0, theImage.size.width, theImage.size.height);
///Why is this SO MUCH faster...
NSDate * startingTimeForUIImageDrawing = [NSDate date];
CGContextDrawImage(ctxt, imgRec, theImage.CGImage); //Draw existing image into context Using the UIImage backing
NSLog(@"Time was %f", [[NSDate date] timeIntervalSinceDate:startingTimeForUIImageDrawing]);
/// Create a new image from the context to use this time in CGContextDrawImage:
CGImageRef theImageConverted = CGBitmapContextCreateImage(ctxt);
///This is WAY slower but why?? Using a pure CGImageRef (ass opposed to one behind a UIImage) seems like it should be faster but AT LEAST it should be the same speed!?
NSDate * startingTimeForNakedGImageDrawing = [NSDate date];
CGContextDrawImage(ctxt, imgRec, theImageConverted);
NSLog(@"Time was %f", [[NSDate date] timeIntervalSinceDate:startingTimeForNakedGImageDrawing]);
}
Итак, я думаю, вопрос в том, # 1, что может быть причиной этого, и # 2, есть ли способ обойти это, то есть другие способы создания CGImageRef, который может быть быстрее?Я понимаю, что могу сначала преобразовать все в UIImages, но это такое уродливое решение.У меня уже есть CGContextRef, сидящий там.
ОБНОВЛЕНИЕ: Это, кажется, не обязательно верно при рисовании маленьких изображений?Это может быть подсказкой - эта проблема усиливается при использовании больших изображений (то есть полноразмерных изображений с камеры).640x480, похоже, довольно схожи по времени выполнения с любым из методов
ОБНОВЛЕНИЕ 2: Хорошо, поэтому я обнаружил что-то новое ... На самом деле это НЕ поддержка CGImage, которая меняет производительность.Я могу перевернуть порядок двух шагов и заставить метод UIImage вести себя медленно, тогда как «голый» CGImage будет очень быстрым.Кажется, что бы вы ни делали вторым, вы будете страдать от ужасного выступления.Это, кажется, имеет место, ЕСЛИ Я не освобождаю память, вызывая CGImageRelease для изображения, которое я создал с CGBitmapContextCreateImage.Тогда метод с поддержкой UIImage будет быстрым впоследствии.Обратное это не правда.Что дает?«Переполненная» память не должна влиять на производительность, как это, не так ли?
ОБНОВЛЕНИЕ 3: Говорили слишком рано.Предыдущее обновление относится к изображениям размером 2048x2048, но с шагом до 1936x2592 (размер камеры) голый метод CGImage все еще медленнее, независимо от порядка операций или ситуации с памятью.Возможно, существуют некоторые внутренние ограничения компьютерной графики, которые делают изображение размером 16 МБ эффективным, тогда как изображение размером 21 МБ не может быть эффективно обработано.Буквально в 20 раз медленнее нарисовать размер камеры, чем 2048x2048.Каким-то образом UIImage предоставляет свои данные CGImage намного быстрее, чем чистый объект CGImage.oO
ОБНОВЛЕНИЕ 4: Я подумал, что это может быть связано с некоторыми вещами кэширования памяти, но результаты одинаковы, независимо от того, загружен ли UIImage с некэширующим [UIImage imageWithContentsOfFile], как если бы [UIImage imageNamed] былиспользуется.
ОБНОВЛЕНИЕ 5 (День 2): После создания вопросов Mroe, на которые были даны ответы вчера, у меня что-то твердое сегодня.Что я могу сказать наверняка, так это:
- CGImage, стоящие за UIImage, не используют альфа.(KCGImageAlphaNoneSkipLast).Я подумал, что, может быть, их быстрее нарисовать, потому что в моем контексте использовалась альфа.Поэтому я изменил контекст, чтобы использовать kCGImageAlphaNoneSkipLast.Это делает рисование НАМНОГО быстрее, ЕСЛИ НЕ:
- Рисование в CGContextRef с UIImage FIRST, замедляет ВСЕ последующее рисование изображений
Я доказал это 1) сначала создав неальфа-контекст (1936x2592).2) Заполнил его случайными цветными квадратами 2х2.3) Полный кадр, рисующий CGImage в этом контексте, был БЫСТРОМ (.17 секунд). 4) Повторял эксперимент, но заполнил контекст нарисованным CGImage, поддерживающим UIImage.Последующее рисование полнокадрового изображения заняло 6+ секунд.SLOWWWWW.
Каким-то образом рисование в контексте с помощью (большого) UIImage резко замедляет все последующие рисования в этом контексте.