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()

我四处寻找,但找不到一种不同的、更有效的方法。谁能帮我克服这个性能问题?谢谢

4

1 回答 1

5

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

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

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

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

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

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

于 2014-09-13T19:53:23.373 回答