2011-07-15 82 views
5

我有一系列想要动画的图像(UIImageView支持一些基本的动画,但它不足以满足我的需要)。iOS:提高图像绘制的速度

我的第一种方法是使用UIImageView并设置image属性当图像。这太慢了。速度不佳的原因是由于图像的绘制(这让我感到吃惊;我认为瓶颈会加载图像)。

我的第二种方法是使用通用UIView并设置view.layer.contents = image.CGImage。这没有带来明显的改善。

这两种方法都必须在主线程上执行。我认为速度不佳是由于必须将图像数据绘制到CGContext

如何提高绘图速度?是否有可能在后台线程上绘制上下文?

回答

0

关于使用UIImageView内置动画服务使用UIImage *(animationImages)数组以及伴随的animationDuration和animationRepeatCount不起作用的动画需求是什么?

如果您正在快速绘制多个图像,请仔细查看Quartz 2D。如果你正在绘画,然后动画(移动,缩放等)图像,你应该看看核心动画。

这听起来像Quartz 2D是你想要的。苹果文档浏览: http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/Introduction/Introduction.html

+0

'UIImageView'不够,因为我需要更多的控制动画序列。例如,循环帧1-10,然后播放帧11-20,然后循环帧21-30。 –

+0

为什么不把它们分解成单独的UIImageView? –

9

我设法做一些事情来提高性能:

  • 我固定我的构建过程,以使PNG图像正在iOS的优化。 (应用程序的内容在一个单独的项目中进行管理,该项目会输出一个包。默认的包设置用于OS X包,它不优化PNG)。

  • 在后台线程I:

    1. 创建一个新的位图上下文(下面的代码)
    2. 德鲁PNG图像到从位图上下文的创建一个CGImageRef位图上下文
    3. 在主线程上设置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; 
} 
+1

您可以将null传递给CGBitmapContextCreate作为第一个参数。它会为你处理内存处理。此外,您必须始终检查malloc的可能失败的返回值。 –