iPhoneカメラプレビュー「ビデオ」にエフェクトを適用
-
28-10-2019 - |
質問
私の目標は、次のようなカスタムカメラビューコントローラーを作成することです。
- 背面カメラと、可能な場合は前面カメラの両方を使用して、4つのインターフェース方向すべてで写真を撮ることができます。
- プレビューの「ビデオ」とフル解像度の写真を適切に回転および拡大縮小します。
- プレビュー「ビデオ」とフル解像度の写真の両方に(単純な)効果を適用できます。
実装(iOS 4.2 / Xcode 3.2.5の場合):
要件(3)のため、AVFoundationにドロップダウンする必要がありました。
テクニカルQ&A QA1702 から始めて、これらを作成しました変更点:
- sessionPresetをAVCaptureSessionPresetPhotoに変更しました。
- セッションを開始する前に、追加の出力としてAVCaptureStillImageOutputを追加しました。
私が抱えている問題は、プレビュー画像(プレビュー「ビデオ」のフレーム)の処理のパフォーマンスにあります。
最初に、
imageFromSampleBuffer:
からサンプルバッファー上のcaptureOutput:didOutputSampleBuffer:fromConnection:
のUIImage結果を取得します。次に、CGGraphicsContextを使用して、画面に合わせて拡大縮小および回転します。この時点で、フレームレートはセッションのビデオ出力で指定されている15 FPSをすでに下回っており、エフェクトを追加すると、10未満または約10に低下します。メモリ不足のためにアプリがすぐにクラッシュします。 。
フレームレートをiPhone4では9FPS、iPod Touch(第4世代)では8FPSに下げることに成功しました。
ディスパッチキューを「フラッシュ」するコードも追加しましたが、実際にどの程度役立つかわかりません。基本的に、8〜10フレームごとに、フレームを処理するのではなく、すぐに戻るように
captureOutput:didOutputSampleBuffer:fromConnection:
に信号を送るフラグが設定されます。フラグは、出力ディスパッチキューでの同期操作が終了した後にリセットされます。この時点では、フレームレートが低くてもかまいませんが、メモリのクラッシュが少ない状態で出荷することはできません。この場合、メモリ不足状態を防ぐためのアクションを実行する方法(および/またはディスパッチキューを「フラッシュ」するためのより良い方法)を知っている人はいますか?
解決
メモリの問題を防ぐには、captureOutput:didOutputSampleBuffer:fromConnection:
で自動解放プールを作成するだけです。
imageFromSampleBuffer:
は自動リリースされたUIImageオブジェクトを返すため、これは理にかなっています。さらに、画像処理コードによって作成された自動解放されたオブジェクトをすぐに解放します。
ジェネラコディセタグプレ
私のテストでは、要求されたFPSが非常に高く(たとえば60)、画像処理が非常に遅い(たとえば、0.5秒以上)場合でも、iPhone4またはiPodTouch(第4世代)でメモリ警告なしで実行されることが示されています。
古いソリューション:
Bradが指摘したように、Appleは、UIの応答性を妨げないように、画像処理をバックグラウンドスレッドで行うことをお勧めします。この場合、大きな遅れには気づきませんでしたが、ベストプラクティスはベストプラクティスであるため、メインディスパッチキュー/メインスレッドで実行する代わりに、自動解放プールで上記のソリューションを使用してください。
メモリの問題を防ぐには、新しいディスパッチキューを作成する代わりに、メインのディスパッチキューを使用するだけです。
これは、UIを更新するときにcaptureOutput:didOutputSampleBuffer:fromConnection:
のメインスレッドに切り替える必要がないことも意味します。
setupCaptureSession
で、FROMを変更します:
ジェネラコディセタグプレ
TO: ジェネラコディセタグプレ
他のヒント
基本的に優れたアプローチは、OpenGLを使用して、画像に関連する手間のかかる作業をできるだけ多く処理することです(最新の試み)。ただし、それでも、処理するフレームの作成で問題が発生する可能性があります。
フレームを処理するときにメモリの蓄積に遭遇するのは奇妙に思えますが(私の経験では、十分な速度で処理できない場合はフレームの取得を停止します)、Grand CentralDispatchキューが詰まる可能性がありますI / Oを待っています。
おそらく、ディスパッチセマフォを使用すると、処理キューへの新しいアイテムの追加を制限できます。これについて詳しくは、MikeAshの「