4

UIImagePickerController を使用して静止画像をキャプチャするプロジェクトを開始しました。オーバーレイとキャプチャしたばかりの画像との相互作用が不十分だったため、この単純なメカニズムの使用を断念しました。問題は次のとおりです。オーバーレイをアクティブにして写真をスナップすると、スナップしたばかりの画像が回転して、縦向きのアスペクト フィルが行われ、ユーザーに画像を使用または再撮影するオプションが表示されます。これが発生した場合、オーバーレイを閉じたり、新しい静止画像プレビューの向きに対応するようにオーバーレイを回転したりする方法はありません。良くない。

AV Foundation のさまざまなメカニズムを使用して、UIImagePickerController の静止画像キャプチャ動作を再実装することにしました。これは驚くほど簡単にセットアップできましたが、まだいくつかの問題が残っています。

1) 標準の UIImagePickerController で UI がどのように機能するかに似るように、メカニズムの方向を変更したいと考えています。このコントローラーでは、ご存じのとおり、携帯電話をどのように回転させても、ボタン バーは常に縦向きの下部に固定されたままです。このボタン バー内では、ボタン自体のグリフが回転しますが、それ以外はすべて固定されたままです。フラッシュ セット、カメラの切り替え、およびオプションのオーバーレイ コントロールは、再配置されます。これらの他の要素を回転させている間、このタブバーを固定したままにするにはどうすればよいですか? 特定の要素を回転から除外する方法はありますか?

2) 自動再配向を行う際に、AVVideoCaptureLayer を常にライブのままにして、画面全体を占有するようにします。デバイスが方向転換の回転を実行すると、このレイヤーのサイズが異常に大きくなり (縮小され)、ビデオ フィード自体が 90 度ずれます。したがって、明らかにこのレイヤーは回転していますが、全画面サイズにはなっておらず、ビデオ フィード自体が期待どおりに動作していません。ビデオを固定したままにして、完全な回転で全画面を占有し、回転中にプレビューのサイズを変更しないでください。しかし、特定の要素を再配置して、項目 1 のようにできるようにしたいです。

これを実現する方法を示すサンプル コードは大歓迎です。

4

3 に答える 3

6

AVCaptureVideoPreviewLayer で orientation プロパティを使用することは非推奨であることがわかりました。ここに更新されたソリューションがあります(ただし、@Jaret Wardが共有した以前のソリューションははるかに少ない作業でした:):

AVCaptureConnection の setVideoOrientation で変更するという推奨アプローチを使用してください。これへの呼び出しを viewDidAppear と回転コールバックの 1 つに追加します。

//setup a connection to the preview layer
AVCaptureConnection *connection;
connection = [self.videoPreviewLayer connection];
[connection setVideoOrientation:[self avOrientationForDeviceOrientation:[[UIDevice currentDevice] orientation]]];

//translate the orientation
 - (AVCaptureVideoOrientation)avOrientationForDeviceOrientation:(UIDeviceOrientation)deviceOrientation {

AVCaptureVideoOrientation result = deviceOrientation;
if ( deviceOrientation == UIDeviceOrientationLandscapeLeft )
    result = AVCaptureVideoOrientationLandscapeRight;
else if ( deviceOrientation == UIDeviceOrientationLandscapeRight )
    result = AVCaptureVideoOrientationLandscapeLeft;
else if( deviceOrientation == UIDeviceOrientationPortrait)
    result = AVCaptureVideoOrientationPortrait;
else if( deviceOrientation == UIDeviceOrientationPortraitUpsideDown)
    result = AVCaptureVideoOrientationPortraitUpsideDown;
return result;
}
于 2013-04-01T05:44:41.603 に答える
3

ビデオ プレビュー レイヤーの接続で方向プロパティを設定する。

これは、@ CocoaEvの回答のよりクリーンなバージョンです。向きをメソッドではなく関数で修正することに加えて、新しいドット構文を使用します。

self.videoPreviewLayer.connection.videoOrientation = AVOrientationFromDeviceOrientation([UIDevice currentDevice].orientation);

AVCaptureVideoOrientation AVOrientationFromDeviceOrientation(UIDeviceOrientation deviceOrientation) {
    if ( deviceOrientation == UIDeviceOrientationLandscapeLeft )
        return AVCaptureVideoOrientationLandscapeRight;
    else if ( deviceOrientation == UIDeviceOrientationLandscapeRight )
        return AVCaptureVideoOrientationLandscapeLeft;
    else if( deviceOrientation == UIDeviceOrientationPortrait)
        return AVCaptureVideoOrientationPortrait;
    else if( deviceOrientation == UIDeviceOrientationPortraitUpsideDown)
        return AVCaptureVideoOrientationPortraitUpsideDown;
    else
        return deviceOrientation;
}
于 2013-04-26T22:24:56.893 に答える
2

私は自分の努力で同様の問題に遭遇し、最終的にビデオストリームに影響を与えるという考えを手放しました. 代わりに、AVCaptureVideoPreviewLayer 自体に注目し、次のソリューションを思いつきました。

- (void)orientationChangedMethod {
    self.previewLayer.orientation = [[UIDevice currentDevice] orientation];
    self.previewLayer.frame = self.view.bounds;
}

ここで、orientationChangedMethod はthe.ichibod.comの (非常に役立つ) コードへの記入であり、self.previewLayer は私の AVCaptureVideoPreviewLayer インスタンスへの参照です。

iOS 6 以降、この回答は非推奨です。

于 2012-05-07T01:27:41.533 に答える