将效果应用于iPhone Camera Preview“视频”
-
28-10-2019 - |
题
我的目标是编写一个自定义的相机视图控制器,该控制器:
- 可以使用后置摄像头和前置摄像头(如果有)在所有四个界面方向拍照。
- 正确旋转和缩放预览“视频”以及全分辨率照片。
- 允许将(简单)效果应用于预览“视频”和全分辨率照片。
实施(在iOS 4.2 / Xcode 3.2.5上):
由于要求(3),我需要下拉至AVFoundation。
我从技术问答QA1702 开始,更改:
- 将sessionPreset更改为AVCaptureSessionPresetPhoto。
- 在开始会话之前,添加了AVCaptureStillImageOutput作为附加输出。
我遇到的问题是处理预览图像(预览“视频”的一帧)的性能。
首先,我从
imageFromSampleBuffer:
获取样本缓冲区上captureOutput:didOutputSampleBuffer:fromConnection:
的UIImage结果。然后,我使用CGGraphicsContext缩放并旋转到屏幕上。在这一点上,帧速率已经低于会话视频输出中指定的15 FPS,当我添加效果时,它降至10以下或大约10。由于内存不足,应用很快崩溃了
在将iPhone 4的帧速率降至9 FPS并将iPod Touch(第4代)的帧速率降至8 FPS方面,我取得了一些成功。
我还添加了一些代码来“刷新”调度队列,但是我不确定它实际上有多大帮助。基本上,每8到10帧设置一个标志,该信号通知
captureOutput:didOutputSampleBuffer:fromConnection:
立即返回而不是处理该帧。在输出调度队列上的同步操作完成后,将重置该标志。在这一点上,我什至都不介意低帧速率,但是显然我们不能随内存不足崩溃而交付。任何人都知道如何在这种情况下采取措施防止内存不足(和/或“刷新”调度队列的更好方法)?
解决方案
要防止出现内存问题,只需在captureOutput:didOutputSampleBuffer:fromConnection:
中创建一个自动释放池即可。
这很有意义,因为imageFromSampleBuffer:
返回了一个自动释放的UIImage对象。另外,它可以立即释放由图像处理代码创建的所有自动释放的对象。
通用标签
我的测试表明,即使请求的FPS非常高(例如60)并且图像处理非常慢(例如0.5+秒),iPhone 4或iPod Touch(第4代)也可以在没有内存警告的情况下运行。 / p>
旧解决方案:
正如Brad所指出的那样,Apple建议在后台线程上进行图像处理,以免干扰UI响应能力。在这种情况下,我没有注意到太多延迟,但是最佳实践是最佳实践,因此将上述解决方案与自动释放池一起使用,而不要在主调度队列/主线程上运行它。
要防止出现内存问题,只需使用主调度队列,而不要创建一个新的队列。
这还意味着,当您要更新UI时,不必切换到captureOutput:didOutputSampleBuffer:fromConnection:
中的主线程。
在setupCaptureSession
中,更改为:
通用标签
收件人: 通用标签