调整 UIImage 大小 - 性能问题

Posted

技术标签:

【中文标题】调整 UIImage 大小 - 性能问题【英文标题】:Resizing UIImage - Performance Issues 【发布时间】:2014-09-13 18:18:52 【问题描述】:

我的目标是使用AVFoundation 来捕获和显示(使用叠加视图)捕获的图像 - 应该与预览层中的图像相同。

使用 iPhone 4" 屏幕尺寸很好,因为它只涉及调整捕获图像的大小。但是,使用 iPhone 3.5" 屏幕尺寸证明更复杂 - 需要调整大小和裁剪。

虽然我的代码适用于两个摄像头位置(正面和背面),但用于调整后置摄像头拍摄的图像大小/裁剪的代码存在一些性能问题。在调整图像大小时,我已将性能问题缩小到更大的图像上下文。需要更大的图像上下文来保持图像“视网膜”质量,而前置摄像头太差了,捕捉到的图像无论如何都不是“视网膜”质量。

有问题的代码是:

UIGraphicsBeginImageContext(CGSizeMake(width, height)) 

// where: width = 640, height = 1138
// image dimensions = 1080 x 1920 

image.drawInRect(CGRectMake(0, 0, width, height))
image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

我四处搜索,但找不到其他更有效的方法。谁能帮我克服这个性能问题?谢谢

【问题讨论】:

【参考方案1】:

您的问题并不完全清楚您的最终输入和输出是什么,以及您的实时要求是什么。我将尝试通过对您正在做什么的一些假设来触及您需要的主要观点。

您的问题中有一个不清楚的决定,但您必须做出决定。如果您在处理方面落后,您会丢帧、丢质量还是滞后输入?这些方法中的每一种都是有效的方法,但您最终必须采用其中一种方法。如果您不选择,系统会为您做出选择(通常会延迟输入,但 AVFoundation 可能会开始为您丢帧,具体取决于您在哪里进行处理)。

关于裁剪的具体问题,您可能想要的工具是CGImageCreateWithImageInRect。这几乎肯定会比您当前的裁剪解决方案快得多(假设您可以及时调整大小,您建议这样做)。

CGImageCreateWithImageInRect 是一种特殊情况,因为它只是窥视现有图像,因此速度非常快。不过,一般来说,您应该尽量避免创建新的CGImageUIImage,而不是绝对必须这样做。您通常想要做的是使用底层CIImage。例如,您可以使用imageByApplyingTransform 转换CIImage 来缩放它,并使用imageByCroppingToRect 来裁剪它。 CIImage 在绝对必要之前避免创建图像。正如文档所说,这确实是图像的“食谱”。您可以将各种过滤器和调整链接在一起,然后将它们全部应用到一次大型 GPU 传输中。将数据转移到 GPU 并返回到 CPU 非常昂贵。你想只做一次。如果您落后并且不得不丢弃帧,您可以丢弃 CIImage 而无需渲染它。

如果您可以访问来自相机的 YUV 数据(如果您使用的是CVPixelBuffer),那么CIImage 会更加强大,因为它可以避免进行 RBGA 转换。 CIImage 还可以关闭颜色管理(如果您只是调整大小和裁剪,这可能无关紧要,但如果您修改颜色则很重要)。关闭色彩管理可能是一个巨大的胜利。对于实时工作,CoreImage 还可以在EAGLContext 中工作并在 GPU 上运行,而不必来回复制到 CPU。如果性能让你吃不消,你想要这些东西。

首先,阅读Core Image Programming Guide 以了解您可以做什么。然后我推荐WWDC 2013 的“Core Image Effects and Techniques”和WWDC 2014 的“Advances in Core Image”。

【讨论】:

以上是关于调整 UIImage 大小 - 性能问题的主要内容,如果未能解决你的问题,请参考以下文章

性能:UIImage 与 UIView

使用 UIImage imageNamed 方法渲染图块的性能问题

如何针对特定目标文件大小优化图像大小?

在 MS-Windows 下调整大小导致的 Tkinter 性能问题

按宽度按比例调整 UIImage 的大小

调整 UIImage 大小的哪种方法更好,为啥?