我的目标是使用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()
我已经四处搜索,但找不到另一种更有效的方法。任何人都可以帮我克服这个性能问题吗?感谢
答案 0 :(得分:5)
从您的问题来看,您的最终输入和输出是什么以及您的实时要求是什么并不完全清楚。我会试着通过一些关于你正在做的事情的假设来触及你需要的主要观点。
你的问题中有一个不明确的决定,但你必须做出决定。如果你在处理方面落后了,你会丢帧,丢弃质量还是滞后输入?这些都是一种有效的方法,但 最终必须做其中一种。如果您不选择,将为您做出选择(通常会延迟输入,但AVFoundation可能会开始为您丢帧,具体取决于您处理的位置)。
关于裁剪的具体问题,您可能需要的工具是CGImageCreateWithImageInRect
。这几乎肯定会比你目前的裁剪解决方案快得多(假设你可以及时调整大小,你建议你可以)。
CGImageCreateWithImageInRect
是一个特例,因为它只是窥视现有的图像,因此可以非常快。但是,一般情况下,您应该强烈避免创建新的CGImage
或UIImage
。您通常要做的是使用基础CIImage
。例如,您可以将CIImage
转换为imageByApplyingTransform
以缩放它,并转换imageByCroppingToRect
来裁剪它。 CIImage
避免在完全必须之前创建图像。正如文档所说,它确实是图像的“配方”。您可以将各种过滤器和调整链接在一起,然后将它们全部应用于一个大GPU传输中。将数据移动到GPU并返回到CPU是非常昂贵的;你想完成一次。如果你落后并且不得不放弃框架,你可以放弃CIImage
而不必渲染它。
如果您可以从相机访问YUV数据(如果您正在使用CVPixelBuffer
),那么CIImage
会更强大,因为它可以避免进行RBGA转换。 CIImage
还可以关闭颜色管理(如果你只是调整大小和裁剪可能无关紧要,但如果你根本修改颜色则无关紧要)。关闭色彩管理可能是一个巨大的胜利。对于实时工作,CoreImage也可以在EAGLContext
中工作并在GPU上运行,而不必在CPU上来回复制。如果表演让你烦恼,你会想要这些东西。
首先,阅读Core Image Programming Guide以了解您可以做些什么。然后我推荐WWDC 2013中的“核心图像效果和技术”和WWDC 2014中的“核心图像进展”。