有什么方法可以比UIImagePNGRepresentation更快地编码PNG?

时间:2013-01-02 02:18:37

标签: ios uiimage catiledlayer cgimageref uiimagepngrepresentation

我正在为CATiledLayer生成一堆图块。在iPhone 4S上以4个级别的细节生成120个256 x 256的图块需要大约11秒钟。图像本身适合2048 x 2048.

我的瓶颈是UIImagePNGRepresentation。生成每256 x 256图像大约需要0.10-0.15秒。

我尝试在不同的背景队列上生成多个图块,但这只会将其减少到大约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图像?也许使用像libjpeg-turbo这样的NEON ARM扩展(iPhone 3GS +)的库呢?

是否有比PNG更好的格式来保存不占用大量空间的瓷砖?

我能够提出的唯一可行选择是将磁贴大小增加到512 x 512.这会将编码时间减少一半。不知道那会对我的滚动视图做些什么。该应用适用于iPad 2+,仅支持iOS 6(使用iPhone 4S作为基线)。

1 个答案:

答案 0 :(得分: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压缩程度较高。