Han*_*Han 5 xcode opencv ios avcapturesession
我正在为iOS编写一个OpenCv Cordova插件.我需要全屏显示相机预览并保持所有iOS设备(iPhone,iPad)的宽高比.
我能够实现人像模式(参见代码)并且在iPhone 6/plus上完美运行但是iPad上的相机预览略有拉伸可能是由于AVCaptureSessionPresetHigh支持的分辨率为1280x720.任何人都有关于如何实现单一方向(仅限横向或纵向)并保持纵横比的任何想法?
我目前启动相机的代码是
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// Initialize imageView to fullscreen
imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.view addSubview:imageView];
[imageView setContentMode:UIViewContentModeScaleAspectFill];
[imageView setClipsToBounds:YES];
self.videoCamera = [[FixedCvVideoCamera alloc] initWithParentView:imageView];
self.videoCamera.delegate = self;
self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionBack;
self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPresetHigh;
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
self.videoCamera.defaultFPS = 30;
[self.videoCamera start];
}
Run Code Online (Sandbox Code Playgroud)
请注意,我使用的是FixedCvVideoCamera而不是OpenCv CvVideoCamera类.其原因是,我继承并重写CvVideoCamera的layoutPreviewLayer功能,以保持纵向模式.
- (void)layoutPreviewLayer;
{
if (self.parentView != nil)
{
CALayer* layer = self->customPreviewLayer;
CGRect bounds = self->customPreviewLayer.bounds;
int rotation_angle = 0;
switch (defaultAVCaptureVideoOrientation) {
case AVCaptureVideoOrientationLandscapeRight:
rotation_angle = 270;
break;
case AVCaptureVideoOrientationPortraitUpsideDown:
rotation_angle = 180;
break;
case AVCaptureVideoOrientationLandscapeLeft:
rotation_angle = 90;
break;
case AVCaptureVideoOrientationPortrait:
default:
break;
}
layer.position = CGPointMake(self.parentView.frame.size.width/2., self.parentView.frame.size.height/2.);
layer.affineTransform = CGAffineTransformMakeRotation( DEGREES_RADIANS(rotation_angle) );
layer.bounds = bounds;
}
}
Run Code Online (Sandbox Code Playgroud)
提前致谢.
我自己解决了.下面的代码将帮助那些只想要一个固定的肖像模式并支持前后摄像头的人.
视图控制器
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// Initialize imageView to fullscreen
imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.view addSubview:imageView];
[imageView setContentMode:UIViewContentModeScaleAspectFill];
[imageView setClipsToBounds:YES];
self.videoCamera = [[FixedCvVideoCamera alloc] initWithParentView:imageView];
self.videoCamera.delegate = self;
self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionBack;
self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPresetHigh;
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
self.videoCamera.defaultFPS = 30;
self.videoCamera.grayscaleMode = NO;
[self.videoCamera start];
}
Run Code Online (Sandbox Code Playgroud)
FixedCvVideoCamera:CvVideoCamera
- (void)layoutPreviewLayer;
{
if (self.parentView != nil)
{
CALayer* layer = self->customPreviewLayer;
CGRect bounds = self->customPreviewLayer.bounds;
NSLog(@"[FixedCvVideoCamera]Custom Preview Layer bounds %fx%f", bounds.size.width, bounds.size.height);
float previewAspectRatio = bounds.size.height / bounds.size.width;
NSLog(@"[FixedCvVideoCamera]Preview aspect ratio %f", previewAspectRatio);
//int rotation_angle = 0;
layer.position = CGPointMake(self.parentView.frame.size.width/2., self.parentView.frame.size.height/2.);
//layer.affineTransform = CGAffineTransformMakeRotation( DEGREES_RADIANS(rotation_angle) );
// Get video feed's resolutions
NSArray* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
AVCaptureDevice* device = nil;
for (AVCaptureDevice *d in devices) {
// Get the default camera device - should be either front of back camera device
if ([d position] == self.defaultAVCaptureDevicePosition) {
device = d;
}
}
// Set the default device if not found
if (!device) {
device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription);
CGSize resolution = CGSizeMake(dimensions.width, dimensions.height);
if (self.defaultAVCaptureVideoOrientation == AVCaptureVideoOrientationPortrait || self.defaultAVCaptureVideoOrientation == AVCaptureVideoOrientationPortraitUpsideDown) {
resolution = CGSizeMake(resolution.height, resolution.width);
}
NSLog(@"[FixedCvVideoCamera]Video feed resolution is %fx%f", resolution.width, resolution.height);
float videoFeedAspectRatio = resolution.height / resolution.width;
NSLog(@"[FixedCvVideoCamera]Video feed's aspect ratio is %f", videoFeedAspectRatio);
// Set layer bounds to ASPECT FILL by expanding either the width or the height
if (previewAspectRatio > videoFeedAspectRatio) {
NSLog(@"[FixedCvVideoCamera] Preview is more rectangular than the video feed aspect ratio. Expanding width to maintain aspect ratio.");
float newWidth = bounds.size.height / videoFeedAspectRatio;
layer.bounds = CGRectMake(0, 0, newWidth, bounds.size.height);
} else {
NSLog(@"[FixedCvVideoCamera] Preview is equally or less rectangular (wider) than the video feed's aspect ratio. Expanding height bound to maintain aspect ratio.");
float newHeight = bounds.size.width * videoFeedAspectRatio;
layer.bounds = CGRectMake(0, 0, bounds.size.width, newHeight);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1438 次 |
| 最近记录: |