加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

iphone – 禁止以任何方向拍摄图像,而不是Portrait AVFoundation

发布时间:2020-12-14 20:04:38 所属栏目:百科 来源:网络整理
导读:我正在使用AVFoundation来显示相机. 我想防止相机本身旋转,因此观看者只能以纵向方式看到照相机,图像只能在纵向模式下拍摄. 我定义支持的界面方向仅支持纵向,视图本身仅以纵向模式显示,但不是相机正在以设备方向旋转 如何强制显示AVFoundation摄像机,只能像U
我正在使用AVFoundation来显示相机.

我想防止相机本身旋转,因此观看者只能以纵向方式看到照相机,图像只能在纵向模式下拍摄.

我定义支持的界面方向仅支持纵向,视图本身仅以纵向模式显示,但不是相机正在以设备方向旋转

如何强制显示AVFoundation摄像机,只能像UIViewController一样拍摄图像?

我的代码设置相机:

AVCaptureVideoPreviewLayer* lay = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.sess];
UIView *view = [self videoPreviewView];
CALayer *viewLayer = [view layer];
[viewLayer setMasksToBounds:YES];
CGRect bounds = [view bounds];
[lay setFrame:bounds];
if ([lay respondsToSelector:@selector(connection)])
 {
   if ([lay.connection isVideoOrientationSupported])
   {
      [lay.connection setVideoOrientation:AVCaptureVideoOrientationPortrait];
    }
 }
 [lay setVideoGravity:AVLayerVideoGravityResizeAspectFill];
 [viewLayer insertSublayer:lay below:[[viewLayer sublayers] objectAtIndex:0]];
 self.previewLayer = lay;

解决方法

这是基于我对你的问题的理解的一些部分答案(与你所拥有的其他答案不同).

您将该应用锁定为纵向.因此,状态栏始终位于手机的顶部,无论手机的方向如何.这成功地锁定了您的界面,包括您的AVCapture界面.但是您也想锁定相机的原始图像进给,以使图像水平线始终与状态栏平行.

这将非常需要连续完成,因此如果您的相机处于45度角,图像将反向旋转45度.否则,大多数时候,图像将无法正确对齐(另一种选择是,直到您的90度定向开关更新,这将使图像旋转90度)始终不成行.

为此,您需要使用Core Motion和加速度计.您想要将手机的Y轴的角度设置为真垂直,并相应地旋转图像.看几何细节:

iPhone orientation — how do I figure out which way is up?

使用Core Motion,从viewDidLoad触发此方法

- (void)startAccelerometerUpdates {
    self.coreMotionManager = [[CMMotionManager alloc] init];
    if ([self.coreMotionManager isAccelerometerAvailable] == YES) {
        CGFloat updateInterval = 0.1;
            // Assign the update interval to the motion manager
        [self.coreMotionManager setAccelerometerUpdateInterval:updateInterval];
        [self.coreMotionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] 
           withHandler: ^(CMAccelerometerData *accelerometerData,NSError *error) {
             CGFloat angle =  -atan2( accelerometerData.acceleration.x,accelerometerData.acceleration.y) 
                               + M_PI ;
             CATransform3D rotate = CATransform3DMakeRotation(angle,1);
             self.previewLayer.transform = rotate;

         }];
    }
}

a

upright

b

45deg

c

90deg

phone held (a) portrait; (b) rotated ~30deg; (c) landscape
.

你可能会发现这有点跳跃,设备运动和视图之间有一点滞后.您可以使用updateInterval播放,并与其他Core Motion诡计更深入地遏制动作. (我还没有把电话正好颠倒过来,如果你把相机面朝下或面朝上,结果是用更新的代码/使用atan2来定义的.

现在的方向是正确的,但你的形象不符合你的观点.您可以做的很多,因为原始相机Feed的格式是由其传感器阵列的物理尺寸固定的.解决方法是缩放图像,以便在各个角度都有足够的多余图像数据,以使您能够裁剪图像以适合所需的纵向格式.

在Interface Builder中:

>将您的previewLayer的视图设置为以超级视图为中心,宽度和高度等于可见图像区域的对角线(sqrt(width2 height2)

或在代码中:

- (void)resizeCameraView
{
    CGSize size = self. videoPreviewView.bounds.size;
    CGFloat diagonal = sqrt(pow(size.width,2)+pow(size.height,2));
    diagonal = 2*ceil(diagonal/2);  //rounding
    self.videoPreviewView.bounds = (CGRect){0,diagonal,diagonal};
}

如果您在代码中执行此操作,那么如果您从viewDidLoad调用它,resizeCameraView应该可以工作.确保self.videoPreviewView是您的IBOutlet对正确视图的引用.

现在,当您拍摄照片时,您将从相机的阵列中捕获整个“原始”图像数据,这将以横向格式捕获.将使用方向标记保存显示旋转.但是您可能想要的是保存照片,如屏幕上所示.这意味着您必须在保存照片之前旋转裁剪照片以匹配您的屏幕视图,并删除它的方向元数据.这是为了解决问题(“部分回答”的另一部分):我怀疑你可能会认为这种整体方法不能让你满足你想要的(我想你真正喜欢的是摄像头传感器,硬件 – 防止装置的旋转以保持水平面稳定).

更新
改变startAccelerometer更新以从atan2而不是acos获得角度,更平滑,并考虑到所有方向,而不需要费力

更新2
从你的评论来看,你的旋转预览图层似乎被卡住了?我无法复制您的错误,它必须是代码或设置中的其他位置.

所以你可以检查干净的代码,我已经把我的解决方案添加到Apple’s AVCam project,所以你可以检查它.这是做什么

>将Motion Motion框架添加到AVCam.

在AVCamViewController.m

> #import< CoreMotion / CoreMotion.h>
>添加我的startAccelerometerUpdates方法
>添加我的resizeCameraView方法(将这两个方法贴在类文件的顶部附近,否则你可能会感到困惑,在该文件中有多个@implementations)
>添加行:[self resizeCameraView];要查看DidLoad(它可以是方法的第一行)
>添加属性
@property(强,非原子)CMMotionManager * coreMotionManager
到@interface(它不需要属性,但是我的方法假定它存在,所以如果你不添加它,你将不得不修改我的方法).

在startAccelerometerUpdates更改此行:

self.previewLayer.transform = rotate;

至:

self.captureVideoPreviewLayer.transform = rotate;

还可以在AVCamViewController.xib中的“对象”列表中移动ToolBar上方的视频预览视图(否则,当您放大它覆盖控件时)

一定要禁用旋转 – 对于iOS< 6.0,这是已经是真的,但是对于6.0,您需要在目标摘要中选择支持方向的纵向. 我认为这是对AVCam所做的更改的完整列表,轮播/方向都很好.我建议你尝试做同样的事情.如果你能让这个工作顺利进行,你就知道你的代码中有一些其他的错误.如果你仍然发现你的旋转棒,我会很好奇地知道你的硬件和软件环境,比如你在测试哪些设备. 我正在XCode 4.6 / OSX10.8.2上进行编译,并进行以下测试:

- iPhone4S  /  iOS5.1  
- iPhone3G  /  iOS6.1  
- iPad mini /  iOS6.1

所有结果平稳准确.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读