iOS: повышение скорости рисования изображений - PullRequest
5 голосов
/ 15 июля 2011

У меня есть последовательность изображений, которую я хочу анимировать (UIImageView поддерживает некоторую базовую анимацию, но ее недостаточно для моих нужд).

Моим первым подходом было использование UIImageView и установка свойства image для изображения. Это было слишком медленно. Причина низкой скорости была в том, что я рисовал изображения (что меня удивило; я предполагал, что горлышко бутылки будет загружать изображение).

Мой второй подход состоял в том, чтобы использовать общий UIView и установить view.layer.contents = image.CGImage. Это не дало заметного улучшения.

Оба эти подхода должны выполняться в главном потоке. Я думаю, что низкая скорость из-за необходимости рисовать данные изображения в CGContext.

Как я могу улучшить скорость рисования? Можно ли нарисовать контекст в фоновом потоке?

Ответы [ 2 ]

9 голосов
/ 16 июля 2011

Мне удалось улучшить производительность, выполнив несколько вещей:

  • Я исправил процесс сборки так, что PNG оптимизировались под iOS.(Контент для приложения управляется в отдельном проекте, который выводит пакет. Настройки пакета по умолчанию относятся к пакету OS X, который не оптимизирует PNG).

  • Нафоновый поток I:

    1. Создание нового контекста растрового изображения (код ниже)
    2. Создание изображения PNG в контексте растрового изображения
    3. Создание CGImageRef из контекста растрового изображения
    4. Установить layer.content в главном потоке для CGImageRef
  • Использовать NSOperationQueue для управления операциями.

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

-(CGImageRef)newCGImageRenderedInBitmapContext //this is a category on UIImage
{
    //bitmap context properties
    CGSize size = self.size;
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * size.width;
    NSUInteger bitsPerComponent = 8;

    //create bitmap context
    unsigned char *rawData = malloc(size.height * size.width * 4);
    memset(rawData, 0, size.height * size.width * 4);    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();    
    CGContextRef context = CGBitmapContextCreate(rawData, size.width, size.height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

    //draw image into bitmap context
    CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), self.CGImage);
    CGImageRef renderedImage = CGBitmapContextCreateImage(context);

    //tidy up
    CGColorSpaceRelease(colorSpace);    
    CGContextRelease(context);
    free(rawData);

    //done!
    //Note that we're not returning an autoreleased ref and that the method name reflects this by using 'new' as a prefix
    return renderedImage;
}
0 голосов
/ 15 июля 2011

Каковы ваши требования к анимации, которые не позволяют использовать встроенный сервис анимации UIImageView, использующий массив UIImages * (animationImages) и сопровождающие animationDuration и animationRepeatCount?

Если вы быстро рисуете несколько изображений, присмотритесь к Quartz 2D. Если вы рисуете, а затем анимируете (перемещаете, масштабируете и т. Д.) Изображение, вам следует взглянуть на Core Animation.

Звучит так, будто Quartz 2D - это то, что вы хотите. Документы Apple здесь: http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/Introduction/Introduction.html

...