2014年12月18日

【iOS SDK】ARのカメラの映像をズームしてみる

ARアプリの開発をよく担当しています。

ARエンジンとしてMetaioなどあるんですが、
カメラの映像をズームしてARをしたいという要望がでたわけですよ

調べた所、ARエンジンとは関係なく普通に実装できるようなのでやってみました


条件はiOS7以上のiPhone5以降の端末であること

残念ながらiPhone4Sではズームはできませんでした
標準のカメラアプリでも、ビデオ撮影モード中のズームはiPhone4Sまでできません。

ARエンジンを実装しているViewControllerに
このヘッダをインポート

#import <AVFoundation/AVFoundation.h>


ピンチジェスチャーにてズームを行うために
ジェスチャーをビューに登録

    UIPinchGestureRecognizer* pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget: self action: @selector(pinchGesture:)];
    [self.view addGestureRecognizer: pinchRecognizer];
    [pinchRecognizer release];

actionの引数に指定したselectorのメソッドを実装しましょう

- (void)pinchGesture:(UIPinchGestureRecognizer*)gestureRecognizer{
    float scale = [gestureRecognizer scale];
}

まずはこれにてピンチジェスチャーによるスケール値の取得ができますね

あとはジェスチャー開始時のカメラのズームスケール値を基準に
拡縮率を設定してカメラに設定すればOKです

// ジェスチャー開始時のカメラのスケール値を取得
    if(gestureRecognizer.state == UIGestureRecognizerStateBegan){
        NSArray* captureDevices = [AVCaptureDevice devicesWithMediaType: AVMediaTypeVideo];
        if(captureDevices && captureDevices.count > 0){
            AVCaptureDevice* device = captureDevices[0];
                _baseZoomScale = device.videoZoomFactor;
        }
    }

baseZoomScaleはメンバー変数でfloat型です
AVCaptureDeviceのdevicesWithMediaTypeにてビデオ対応のデバイスリストを取得します
背面カメラとFaceTime用カメラの2個が取得できるので
0番目を指定して背面カメラデバイスのインスタンスを取得

videoZoomFacotrプロパティにて現在のズーム倍率が取得できます
これがiOS7以降から使えるものなのでiOS6以前ではダメです
iOS6もカバーする場合はきちんと分岐をしましょう

ジェスチャー開始時のズーム値を取得したら
ジェスチャー中のスケール値増減を反映してカメラに返しましょう

    float currentZoomScale = _baseZoomScale;
    NSArray* captureDevices = [AVCaptureDevice devicesWithMediaType: AVMediaTypeVideo];
    if(captureDevices && captureDevices.count > 0){
        AVCaptureDevice* device = captureDevices[0];
        if([device lockForConfiguration: nil]){
            float maxZoomScale = device.activeFormat.videoMaxZoomFactor;
            currentZoomScale *= scale;
            if(currentZoomScale < 1.0f){
                currentZoomScale = 1.0f;
            }
            else if(maxZoomScale < currentZoomScale){
                currentZoomScale = maxZoomScale;
            }
            NSLog(@"currentZoomScale = %f", currentZoomScale);
            device.videoZoomFactor = currentZoomScale;
            [device unlockForConfiguration];
        }
    }

メンバ変数の値を変化させては意味がないので
いったんローカル変数に値をコピーします

→    float currentZoomScale = _baseZoomScale;

デバイスの情報を更新するのでロックをかける手続きを行います

→ [device lockForConfiguration: nil]

これしないとエラーが発生してアプリが終了します

デバイスの最大ズーム値を取得します

→ float maxZoomScale = device.activeFormat.videoMaxZoomFactor;

今回のジェスチャーで求められたスケール値を基準ズーム値と掛けあわせます

→ currentZoomScale *= scale;

これをデバイスに設定します

→ device.videoZoomFactor = currentZoomScale;

ロックを解除して終了です

→ [device unlockForConfiguration];


videoZoomFactorに指定する数値は 1〜 videoMaxZoomFactorの値 までになっているため
その値を範囲内になるように調整をしています。

この範囲を超えるとエラーが発生してしまうので注意

ちなみに標準カメラのズーム処理はある程度のところで上限をいれているようです
iPhone6で確認するとvideoMaxZoomFactorは100をこえる数値がかえってくるので
ズーム100倍率にしたところで何が映っているかさっぱりわかりませんw

videoMaxZoomFactorの値までの範囲内で上限数値をきめて設計するといいと思います。




ラベル:Xcode
posted by ヒイロ at 14:27| 福岡 ☁| Comment(0) | TrackBack(0) | プログラム | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック