似乎CGContextDrawImage(CGContextRef, CGRect, CGImageRef)在绘制使用CoreGraphics创建的CGImage(例如,使用CGBitmapContextCreateImage)时的性能要比绘制UIImage支持的CGImage差得多。参见以下测试方法:
-(void)showStrangePerformanceOfCGContextDrawImage
{
///Setup : Load an image and start a context:
UIImage *theImage = [UIImage imageNamed:@"reallyBigImage.png"];
UIGraphicsBeginImageContext(theImage.size);
CGContextRef ctxt = UIGraphicsGetCurrentContext();
CGRect imgRec = CGRectMake(0, 0, theImage.size.width, theImage.size.height);
///Why is this SO MUCH faster...
NSDate * startingTimeForUIImageDrawing = [NSDate date];
CGContextDrawImage(ctxt, imgRec, theImage.CGImage); //Draw existing image into context Using the UIImage backing
NSLog(@"Time was %f", [[NSDate date] timeIntervalSinceDate:startingTimeForUIImageDrawing]);
/// Create a new image from the context to use this time in CGContextDrawImage:
CGImageRef theImageConverted = CGBitmapContextCreateImage(ctxt);
///This is WAY slower but why?? Using a pure CGImageRef (ass opposed to one behind a UIImage) seems like it should be faster but AT LEAST it should be the same speed!?
NSDate * startingTimeForNakedGImageDrawing = [NSDate date];
CGContextDrawImage(ctxt, imgRec, theImageConverted);
NSLog(@"Time was %f", [[NSDate date] timeIntervalSinceDate:startingTimeForNakedGImageDrawing]);
}
所以我想问的是,#1这可能是什么原因导致的?#2是否有其他方法可以创建CGImageRef并且更快? 我知道我可以先将一切转换为UIImages,但那太丑陋了。我已经有了CGContextRef sitting there。更新:当绘制小图像时,这似乎并不一定正确?这可能是一个线索——当使用大图像(即全尺寸相机照片)时,这个问题会被放大。640x480看起来在执行时间方面与任何方法都很相似。
更新2:好吧,我发现了一个新的东西...实际上并不是CGImage的支撑变化了性能。我可以颠倒两个步骤的顺序,使UIImage方法表现缓慢,而“裸”的CGImage将会超级快。似乎无论你第二次执行哪个操作,它都会遭受可怕的性能损失。除非我通过在由CGBitmapContextCreateImage创建的图像上调用CGImageRelease来释放内存。然后UIImage支持的方法随后将快速执行。反之则不成立。拥挤的内存不应该像这样影响性能,对吗?
更新3:说得太早了。以前的更新对于2048x2048大小的图像是正确的,但是升级到1936x2592(相机大小)时,裸的CGImage方法仍然要慢得多,无论操作顺序或内存情况如何。也许有一些CG内部限制,使16MB图像有效,而21MB图像则不能有效处理。 以相机大小绘制的速度比2048x2048慢20倍。不知何故,UIImage提供其CGImage数据比纯CGImage对象快得多。
更新4:我认为这可能与某些内存缓存事物有关,但是结果与使用非缓存[UIImage imageWithContentsOfFile]加载UIImage的结果相同,就像使用[UIImage imageNamed]一样。
更新5(第二天):在昨天创建了更多未回答的问题之后,今天我有了一些确凿的东西。 我可以确定以下内容:
- 在UIImage背后的CGImages不使用alpha。 (kCGImageAlphaNoneSkipLast)。我认为它们可能更快地被绘制,因为我的上下文正在使用alpha。所以我将上下文更改为使用kCGImageAlphaNoneSkipLast。这使得绘图速度大为提高,除非: - 首先使用UIImage在CGContextRef中进行绘制会使所有随后的图像绘制变慢。
我通过以下方式证明了这一点:
1)首先创建一个无alpha上下文(1936x2592);
2)填充它的颜色为随机着色的2x2方块;
3)将CGImage完全绘制到该上下文中,速度很快(0.17秒);
4)重复实验,但使用绘制CGImage支持UIImage的上下文来填充上下文。随后全部帧图像绘制都需要6秒以上时间。
以某种方式,在具有(大型)UIImage的上下文中进行绘图会显着减慢对该上下文的所有随后绘图。