sol*_*eil 56 avfoundation orientation ios avcapture avcapturesession
我的应用只是风景.我将这样呈现AVCaptureVideoPreviewLayer:
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[self.previewLayer setBackgroundColor:[[UIColor blackColor] CGColor]];
[self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
NSLog(@"previewView: %@", self.previewView);
CALayer *rootLayer = [self.previewView layer];
[rootLayer setMasksToBounds:YES];
[self.previewLayer setFrame:[rootLayer bounds]];
NSLog(@"previewlayer: %f, %f, %f, %f", self.previewLayer.frame.origin.x, self.previewLayer.frame.origin.y, self.previewLayer.frame.size.width, self.previewLayer.frame.size.height);
[rootLayer addSublayer:self.previewLayer];
[session startRunning];
Run Code Online (Sandbox Code Playgroud)
self.previewView的框架为(0,0,568,320),这是正确的.self.previewLayer记录一个(0,0,568,320)的帧,这在理论上是正确的.但是,相机显示在横向屏幕中间显示为纵向矩形,并且相机预览图像的方向错误90度.我究竟做错了什么?我需要相机预览层出现在全屏幕,在横向模式下,图像应正确导向.
Mas*_*lko 65
SWIFT 3.0和XCODE 8.0的最佳答案
private func updatePreviewLayer(layer: AVCaptureConnection, orientation: AVCaptureVideoOrientation) {
layer.videoOrientation = orientation
previewLayer.frame = self.view.bounds
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let connection = self.previewLayer?.connection {
let currentDevice: UIDevice = UIDevice.current
let orientation: UIDeviceOrientation = currentDevice.orientation
let previewLayerConnection : AVCaptureConnection = connection
if previewLayerConnection.isVideoOrientationSupported {
switch (orientation) {
case .portrait: updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)
break
case .landscapeRight: updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeLeft)
break
case .landscapeLeft: updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeRight)
break
case .portraitUpsideDown: updatePreviewLayer(layer: previewLayerConnection, orientation: .portraitUpsideDown)
break
default: updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)
break
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
SWIFT 2.2和XCODE 7.3的最佳答案
private func updatePreviewLayer(layer: AVCaptureConnection, orientation: AVCaptureVideoOrientation) {
layer.videoOrientation = orientation
previewLayer.frame = self.view.bounds
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let connection = self.previewLayer?.connection {
let currentDevice: UIDevice = UIDevice.currentDevice()
let orientation: UIDeviceOrientation = currentDevice.orientation
let previewLayerConnection : AVCaptureConnection = connection
if (previewLayerConnection.supportsVideoOrientation) {
switch (orientation) {
case .Portrait: updatePreviewLayer(previewLayerConnection, orientation: .Portrait)
break
case .LandscapeRight: updatePreviewLayer(previewLayerConnection, orientation: .LandscapeLeft)
break
case .LandscapeLeft: updatePreviewLayer(previewLayerConnection, orientation: .LandscapeRight)
break
case .PortraitUpsideDown: updatePreviewLayer(previewLayerConnection, orientation: .PortraitUpsideDown)
break
default: updatePreviewLayer(previewLayerConnection, orientation: .Portrait)
break
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Kha*_*azi 64
默认摄像机方向为横向左侧(左侧是主页按钮).你需要在这里做两件事:
1-将previewLayer框架更改为:
self.previewLayer.frame=self.view.bounds;
Run Code Online (Sandbox Code Playgroud)
您需要将预览图层框架设置为屏幕边界,以便在屏幕旋转时预览图层的框架发生更改(您不能使用根视图的框架,因为它不会随着旋转而改变,而是根视图的边界做).在您的示例中,您将预览层框架设置为我看不到的previewView属性.
2-您需要通过设备的旋转来旋转预览图层连接.在viewDidAppear中添加此代码:
-(void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
//Get Preview Layer connection
AVCaptureConnection *previewLayerConnection=self.previewLayer.connection;
if ([previewLayerConnection isVideoOrientationSupported])
[previewLayerConnection setVideoOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}
Run Code Online (Sandbox Code Playgroud)
希望这能解决它.
完全披露:这是一个简化版本,因为您不关心Landscape Right还是Landscape.
Jan*_*ski 27
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
if let connection = self.previewLayer?.connection {
var currentDevice: UIDevice = UIDevice.currentDevice()
var orientation: UIDeviceOrientation = currentDevice.orientation
var previewLayerConnection : AVCaptureConnection = connection
if (previewLayerConnection.supportsVideoOrientation) {
switch (orientation) {
case .portrait:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.portrait
case .landscapeRight:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.landscapeRight
case .landscapeLeft:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.landscapeLeft
case .portraitUpsideDown:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.portraitUpsideDown
default:
previewLayerConnection.videoOrientation = AVCaptureVideoOrientation.portrait
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 16
我们不能用
[previewLayerConnection setVideoOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
Run Code Online (Sandbox Code Playgroud)
因为 UIInterfaceOrientation != AVCaptureVideoOrientation
但是我们可以通过以下代码测试值...并且这项工作.
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
switch (orientation) {
case UIInterfaceOrientationPortrait:
[_videoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationPortrait];
break;
case UIInterfaceOrientationPortraitUpsideDown:
[_videoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationPortraitUpsideDown];
break;
case UIInterfaceOrientationLandscapeLeft:
[_videoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeLeft];
break;
case UIInterfaceOrientationLandscapeRight:
[_videoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
break;
}
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*ers 14
API似乎有所改变.videoOrientation
现在是预览图层connection
属性的属性.此外,无需使用开关.Swift 3.0的答案:
override func viewDidLayoutSubviews() {
self.configureVideoOrientation()
}
private func configureVideoOrientation() {
if let previewLayer = self.previewLayer,
let connection = previewLayer.connection {
let orientation = UIDevice.current.orientation
if connection.isVideoOrientationSupported,
let videoOrientation = AVCaptureVideoOrientation(rawValue: orientation.rawValue) {
previewLayer.frame = self.view.bounds
connection.videoOrientation = videoOrientation
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于那些正在全功能相机预览中苦苦挣扎的人.这是生产代码.当然,缺点是方向改变时滞后.如果有人有更好的解决方案来克服这个,请分享
- (void)viewDidLoad
{
[super viewDidLoad];
[self initCamera];
}
- (void)initCamera
{
AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] error:nil];
if (captureInput) {
mSession = [[AVCaptureSession alloc] init];
[mSession addInput:captureInput];
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
if ([mSession isRunning]) {
[mSession stopRunning];
[mCameraLayer removeFromSuperlayer];
[self initCamera];
[self startCamera];
}
}
- (void)startCamera
{
[mSession startRunning];
Settings::getInstance()->setClearColor(Color(0, 0, 0, 0));
mCameraLayer = [AVCaptureVideoPreviewLayer layerWithSession: mSession];
[self updateCameraLayer];
[mCameraView.layer addSublayer:mCameraLayer];
}
- (void)stopCamera
{
[mSession stopRunning];
[mCameraLayer removeFromSuperlayer];
Settings::getInstance()->setDefClearColor();
}
- (void)toggleCamera
{
mSession.isRunning ? [self stopCamera] : [self startCamera];
[mGLKView setNeedsDisplay];
}
- (void)updateCameraLayer
{
mCameraLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
mCameraLayer.frame = mCameraView.bounds;
float x = mCameraView.frame.origin.x;
float y = mCameraView.frame.origin.y;
float w = mCameraView.frame.size.width;
float h = mCameraView.frame.size.height;
CATransform3D transform = CATransform3DIdentity;
if (UIDeviceOrientationLandscapeLeft == [[UIDevice currentDevice] orientation]) {
mCameraLayer.frame = CGRectMake(x, y, h, w);
transform = CATransform3DTranslate(transform, (w - h) / 2, (h - w) / 2, 0);
transform = CATransform3DRotate(transform, -M_PI/2, 0, 0, 1);
} else if (UIDeviceOrientationLandscapeRight == [[UIDevice currentDevice] orientation]) {
mCameraLayer.frame = CGRectMake(x, y, h, w);
transform = CATransform3DTranslate(transform, (w - h) / 2, (h - w) / 2, 0);
transform = CATransform3DRotate(transform, M_PI/2, 0, 0, 1);
} else if (UIDeviceOrientationPortraitUpsideDown == [[UIDevice currentDevice] orientation]) {
mCameraLayer.frame = mCameraView.bounds;
transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
} else {
mCameraLayer.frame = mCameraView.bounds;
}
mCameraLayer.transform = transform;
}
enter code here
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
45439 次 |
最近记录: |