调整UIImage大小-性能问题

3
我的目标是使用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个回答

5
从你的问题中并不完全清楚你最终的输入和输出是什么,以及你的实时要求是什么。我将尝试涉及你需要的主要点,假设你正在做什么。
在你的问题中有一个不清楚的决定,但你必须做出选择。如果处理落后,你会丢掉帧数、丢失质量还是延迟输入?每一种方法都是有效的,但你最终必须做其中之一。如果你没有选择,就会为你做出选择(通常是延迟输入,但根据你的处理位置,AVFoundation可能会开始为你丢弃帧)。
对于裁剪的具体问题,你可能想要使用的工具是CGImageCreateWithImageInRect。 假设你可以及时调整大小,这几乎肯定比当前解决方案快得多。
CGImageCreateWithImageInRect是一个特殊情况,因为它只是查看现有图像,所以可以非常快速。 但是一般来说,你应该尽可能地避免创建新的CGImage或UIImage。 你通常想要做的是使用底层的CIImage。例如,你可以使用imageByApplyingTransform来转换CIImage以缩放它,使用imageByCroppingToRect来裁剪它。CIImage避免创建图像直到它绝对必须这样做。正如文档所说,它实际上是图像的“配方”。 你可以连接各种滤镜和调整,然后在一个大的GPU传输中应用所有这些过程。将数据从GPU移动回CPU非常昂贵。你只想这样做一次。如果你落后并且不得不丢掉帧数,则可以在未渲染CIImage的情况下丢弃CIImage。
如果你可以从相机访问YUV数据(如果你正在使用CVPixelBuffer),则CIImage更加强大,因为它可以避免执行RBGA转换。 CIImage还具有关闭颜色管理的功能(如果你只是调整大小和裁剪,则可能无关紧要,但如果你修改了颜色,则很重要)。关闭颜色管理可能是一个很大的优势。对于实时工作,CoreImage还可以在EAGLContext中工作,并且生活在GPU上,而无需复制到CPU并返回。如果性能受到影响,你需要这些东西。

首先,阅读Core Image编程指南以了解您可以做什么。然后我建议观看来自WWDC 2013的“核心图像效果和技术”以及来自WWDC 2014的“Core Image的进步”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接