問題点
- CvVideoCameraのアスペクト比がおかしい
-
UIViewContentModeScaleToFill
の状態。
事前調査
- カメラ画像を表示しているUIImageViewの
contentMode
を変更しても反映されない。 - CALayerがなんたらかんたら。
- カメラの動作を開始しないとカメラの解像度が確定しない。
- 動作開始後に調整しないといけない。
- カテゴリを使って既存クラスを拡張できる。(メソッドの追加)
- CvVideoCameraに
startWithContentMode:
を追加する。
完成品
CvVideoCamera+ContentMode.h
# import <UIKit/UIKit.h>
# import <opencv2/highgui/cap_ios.h>
@interface CvVideoCamera (WithContentMode)
- (void)startWithContentMode:(UIViewContentMode)contentMode;
@end
CvVideoCamera+ContentMode.m
# import <AVFoundation/AVFoundation.h>
# import <CoreGraphics/CoreGraphics.h>
# import <CoreMedia/CoreMedia.h>
# import <Foundation/Foundation.h>
# import <QuartzCore/QuartzCore.h>
# import <UIKit/UIKit.h>
# import "CvVideoCamera+ContentMode.h"
@implementation CvVideoCamera (WithContentMode)
- (void)startWithContentMode:(UIViewContentMode)contentMode
{
[self start];
//カメラの解像度を調べる
AVCaptureInput *input = [self.captureSession.inputs objectAtIndex:0];
AVCaptureInputPort *port = [input.ports objectAtIndex:0];
CMFormatDescriptionRef formatDescription = port.formatDescription;
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
NSLog( @"dimensions=%dx%d", dimensions.width, dimensions.height );
if( parentView.layer.sublayers != nil )
{
CALayer *layer = [parentView.layer.sublayers objectAtIndex:0];
NSLog( @"[before] frame%@ position%@", NSStringFromCGRect(layer.frame), NSStringFromCGPoint(layer.position) );
//現在のアスペクト比
CGFloat ratiox = dimensions.width / layer.frame.size.width;
CGFloat ratioy = dimensions.height / layer.frame.size.height;
//contentModeによる表示サイズ/位置の決定
switch( contentMode )
{
case UIViewContentModeScaleAspectFit:
ratiox = (ratiox > ratioy)? ratiox : ratioy;
ratioy = ratiox;
break;
case UIViewContentModeScaleAspectFill:
ratiox = (ratiox < ratioy)? ratiox : ratioy;
ratioy = ratiox;
break;
default:
NSLog( @"does not support" );
break;
}
NSLog( @"ratio(%.3f,%.3f)", ratiox, ratioy );
//新しい表示サイズ/位置をセット
CGFloat x, y, w, h;
w = dimensions.width / ratiox;
h = dimensions.height / ratioy;
x = (layer.frame.size.width - w)/2;
y = (layer.frame.size.height - h)/2;
layer.frame = CGRectMake( x, y, w, h );
NSLog( @"[after] frame%@ position%@", NSStringFromCGRect(layer.frame), NSStringFromCGPoint(layer.position) );
}
}
@end
使い方など
-
start
の代わりにstartWithContentMode:
を呼ぶ。 -
ScaleAspectFit
とScaleAspectFill
のみ対応。 - 対症療法的に作ったので色々と不安。