似乎 CGContextDrawImage(CGContextRef, CGRect, CGImageRef) 在绘制由 CoreGraphics(即使用 CGBitmapContextCreateImage)创建的 CGImage 时比在绘制支持 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 坐在那里。
更新:绘制小图像时,这似乎不一定是真的?这可能是一个线索——当使用大图像(即全尺寸相机照片)时,这个问题会被放大。640x480 在执行时间方面似乎与任何一种方法都非常相似
更新 2:好的,所以我发现了一些新的东西。它实际上不是改变性能的 CGImage 的支持。我可以翻转 2 个步骤的顺序,使 UIImage 方法运行缓慢,而“裸”CGImage 会非常快。似乎无论你第二次表演,都会遭受糟糕的表现。除非我通过在使用 CGBitmapContextCreateImage 创建的图像上调用 CGImageRelease 来释放内存,否则似乎就是这种情况。然后 UIImage 支持的方法随后会很快。反之则不成立。是什么赋予了?“拥挤”的内存不应该像这样影响性能,不是吗?
更新3:说得太早了。之前的更新适用于尺寸为 2048x2048 的图像,但升级到 1936x2592(相机尺寸)时,裸 CGImage 方法仍然慢得多,无论操作顺序或内存情况如何。也许有一些 CG 内部限制使 16MB 图像高效,而 21MB 图像无法有效处理。绘制相机尺寸比 2048x2048 慢 20 倍。不知何故,UIImage 提供它的 CGImage 数据比纯 CGImage 对象快得多。oO
更新 4:我认为这可能与一些内存缓存有关,但是无论 UIImage 是否加载了非缓存 [UIImage imageWithContentsOfFile],结果都是相同的,就像使用 [UIImage imageNamed] 一样。
更新 5(第 2 天):在创建了比昨天回答的问题之后,我今天有了一些扎实的东西。我可以肯定地说的是:
- UIImage 后面的 CGImages 不使用 alpha。(kCGImageAlphaNoneSkipLast)。我认为也许它们绘制得更快,因为我的上下文使用的是 alpha。所以我更改了上下文以使用 kCGImageAlphaNoneSkipLast。这使得绘图速度更快,除非:
- 使用 UIImage FIRST 绘制到 CGContextRef 中,使所有后续图像绘制速度变慢
我通过 1) 首先创建一个非 alpha 上下文 (1936x2592) 证明了这一点。2) 用随机颜色的 2x2 方块填充它。3) 将 CGImage 绘制到该上下文中的全帧速度很快(0.17 秒) 4) 重复实验,但使用支持 UIImage 的绘制 CGImage 填充上下文。随后的全帧图像绘制时间超过 6 秒。慢速万维网。
不知何故,使用(大)UIImage 绘制到上下文中会大大减慢所有后续绘制到该上下文中的速度。