2011-07-15 86 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的可能失敗的返回值。 –