12

我正在爲CATiledLayer生成一堆瓷磚。大約需要11秒,在iPhone 4S上以256 x 256和4級細節生成120個貼圖。圖像本身適合2048 x 2048.任何方式來編碼PNG比UIImagePNGRepresentation更快?

我的瓶頸是UIImagePNGRepresentation。大約需要0.10-0.15秒來生成每個256 x 256圖像。

我試過在不同的背景隊列上生成多個貼圖,但這隻能將其縮小到9-10秒左右。

我也使用的ImageIO框架,這樣的代碼嘗試:

- (void)writeCGImage:(CGImageRef)image toURL:(NSURL*)url andOptions:(CFDictionaryRef) options 
{ 
    CGImageDestinationRef myImageDest = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, (__bridge CFStringRef)@"public.png", 1, nil); 
    CGImageDestinationAddImage(myImageDest, image, options); 
    CGImageDestinationFinalize(myImageDest); 
    CFRelease(myImageDest); 
} 

雖然這將產生更小的PNG文件(贏了!),它需要大約13秒,2秒​​比以前多。

有什麼辦法可以更快地編碼從CGImage的PNG圖像?也許一個庫,使用NEON ARM擴展(iPhone 3GS +),如libjpeg-turbo呢?

是否有比PNG更好的格式來保存不佔用大量空間的瓷磚?

我已經能夠提出的唯一可行的選擇是將圖塊大小增加到512 x 512.這將編碼時間減半。不知道那會對我的滾動視圖做什麼。該應用程序適用於iPad 2+,並且僅支持iOS 6(使用iPhone 4S作爲基準)。

回答

4

原來爲什麼UIImageRepresentation正在執行如此糟糕,是因爲它每次即使我以爲我與CGImageCreateWithImageInRect創建一個新的圖像解壓縮原始圖像的原因。

你可以看到從這裏儀器的結果:

enter image description here

通知_cg_jpeg_read_scanlinesdecompress_onepass

力解壓縮的圖像與此:

UIImage *image = [UIImage imageWithContentsOfFile:path]; 
UIGraphicsBeginImageContext(CGSizeMake(1, 1)); 
[image drawAtPoint:CGPointZero]; 
UIGraphicsEndImageContext(); 

這樣做的時機是約0.10秒,幾乎等同於由每個UIImageRepresentation呼叫所需的時間。

在互聯網上有許多文章推薦繪圖作爲強制解壓縮圖像的一種方式。

有一篇關於Cocoanetics Avoiding Image Decompression Sickness的文章。該文章提供了另一種加載圖像的方法:

NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] 
               forKey:(id)kCGImageSourceShouldCache]; 
CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)[[NSURL alloc] initFileURLWithPath:path], NULL); 
CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, (__bridge CFDictionaryRef)dict); 
UIImage *image = [UIImage imageWithCGImage:cgImage]; 
CGImageRelease(cgImage); 
CFRelease(source); 

而現在相同的過程大約需要3秒鐘!使用GCD並行生成切片可以更加顯着地縮短時間。

上面的writeCGImage功能大約需要5秒。由於文件大小較小,我懷疑zlib壓縮處於更高的級別。