カメラ系のプチトピックです。
AVFoundationをつかってカメラの機能を使う時に、本体の向きをカメラAPIに伝える必要がありました。この伝達をしないと、横向きで写真を撮った時におかしくなります。
例えば
↑ という被写体があったとして、iphoneのホームボタンを右にして写真を撮った場合、
カメラAPIは本体が横を向いているのがわからないため、撮った写真は、
→ として出力しちゃうんですね。
でもユーザーはちゃんと
↑ というのを横幅多めで出力されるのを期待するわけです。
それが正常な挙動としてしまうのも一つですが、普通の挙動を目指すなら対応した方がいいと思います。
まずは本体の回転の通知を受けましょう
1行目が落とし穴で、きちんとこれを呼んでおかないと、向きを正しく返さないよ、
とリファレンスに書いてありました。
呼び出す順番には注意を払いたいところです。
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIDevice_Class/Reference/UIDevice.html
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onOrientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
そしてきちんと終了処理も書いておきましょう
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
面倒なのが、[UIDevice currentDevice].orientationや通知センターで得られる向きは、
UIDeviceOrientationであって、AVFoundationが欲しがっているAVCaptureVideoOrientationとは違うという点です。
しかも左が右だったりUnknownや上向いてる、なんかが定義されています。
ヘッダーに書いてありますので、一つ一つ確認していきます。
AVCaptureVideoOrientationPortrait ホームボタンが下
AVCaptureVideoOrientationPortraitUpsideDown ホームボタンが上
AVCaptureVideoOrientationLandscapeRight ホームボタンが右
AVCaptureVideoOrientationLandscapeLeft ホームボタンが左
UIDeviceOrientationUnknown エラー?
UIDeviceOrientationPortrait ホームボタンが下
UIDeviceOrientationPortraitUpsideDown ホームボタンが上
UIDeviceOrientationLandscapeLeft ホームボタンが右
UIDeviceOrientationLandscapeRight ホームボタンが左
UIDeviceOrientationFaceUp 画面が上向いてる
UIDeviceOrientationFaceDown 画面が下向いてる
あとは対応を記述するだけですね
static AVCaptureVideoOrientation videoOrientationFromDeviceOrientation(UIDeviceOrientation deviceOrientation)
{
AVCaptureVideoOrientation orientation;
switch (deviceOrientation) {
case UIDeviceOrientationUnknown:
orientation = AVCaptureVideoOrientationPortrait;
break;
case UIDeviceOrientationPortrait:
orientation = AVCaptureVideoOrientationPortrait;
break;
case UIDeviceOrientationPortraitUpsideDown:
orientation = AVCaptureVideoOrientationPortraitUpsideDown;
break;
case UIDeviceOrientationLandscapeLeft:
orientation = AVCaptureVideoOrientationLandscapeRight;
break;
case UIDeviceOrientationLandscapeRight:
orientation = AVCaptureVideoOrientationLandscapeLeft;
break;
case UIDeviceOrientationFaceUp:
orientation = AVCaptureVideoOrientationPortrait;
break;
case UIDeviceOrientationFaceDown:
orientation = AVCaptureVideoOrientationPortrait;
break;
}
return orientation;
}
で、あとはAVFoundation側に伝えます。
AVCaptureStillImageOutput *imageOutput;
としてクラスが定義されていれば、
for(AVCaptureConnection *connection in imageOutput.connections)
{
if(connection.supportsVideoOrientation)
{
connection.videoOrientation = videoOrientationFromDeviceOrientation([UIDevice currentDevice].orientation);
}
}
等の様に書いておけば良いでしょう。
こういうちょっとしたことだけど、意外と気づかないことって結構ありますよね。
今回のケースではいつも縦で撮影する人には盲点になりがちな対応でした。