Apple是否使用黑魔法来完成相机的预览定位?

时间:2017-03-12 17:06:36

标签: ios iphone camera avfoundation

我有我的AVFoundation相机应用程序。相机预览是过滤器的结果,由didOutputSampleBuffer方法应用。

当我设置相机时,我正在关注苹果对其中一个示例代码(CIFunHouse)所做的事情:

  // setting up the camera 
  CGRect bounds = [self.containerOpenGL bounds];

  _eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];

  _videoPreviewView = [[GLKView alloc] initWithFrame:bounds
                                             context:_eaglContext];

  [self.containerOpenGL addSubview:_videoPreviewView];
  [self.containerOpenGL sendSubviewToBack:_videoPreviewView];

  id<MTLDevice> device = MTLCreateSystemDefaultDevice();

  NSDictionary *options = @{kCIContextUseSoftwareRenderer : @(NO),
                            kCIContextPriorityRequestLow : @(YES),
                            kCIContextWorkingColorSpace : [NSNull null]};

  _ciContext = [CIContext contextWithEAGLContext:_eaglContext options:options];

  [_videoPreviewView bindDrawable];
  _videoPreviewViewBounds = CGRectZero;
  _videoPreviewViewBounds.size.width = _videoPreviewView.drawableWidth;
  _videoPreviewViewBounds.size.height = _videoPreviewView.drawableHeight;

  dispatch_async(dispatch_get_main_queue(), ^(void) {
    CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI);

    _videoPreviewView.transform = transform; 
    _videoPreviewView.frame = bounds;

  });

self.containerOpenGL是全屏视图,仅限于屏幕的四个角。自动旋转已开启。

但这就是问题......

当我设置GLKViewself.ciContext时,假设设备处于特定方向,则会创建它。如果设备处于特定方向并且我运行应用程序,previewView将适合整个self.containerOpenGL区域,但是当我旋转设备时,previewView将偏离中心。

我看到Apple代码完美无缺,并且他们不会使用任何约束。它们不使用任何自动旋转方法,不使用didLayoutSubviews,当您旋转设备时,运行其代码时,除预览视图外,所有内容都会旋转。更糟糕的是,previewView似乎在旋转,但不是他们的。

这是黑魔法吗?我怎么做到这一点?

1 个答案:

答案 0 :(得分:1)

他们将预览视图添加到uiwindow,这就是它不旋转的原因。我希望这能回答这个问题。如果没有,我会继续浏览他们的源代码。

从源代码引用。

  

我们将视频预览视图设为窗口的子视图,并将其发送到后面;这会使FHViewController的视图(及其UI元素)位于视频预览之上,并且还可以使视频预览不受设备旋转的影响

他们也添加了这个

_videoPreviewView.enableSetNeedsDisplay = NO;

这可能会使它无法响应

编辑:现在预览旋转,UI也一样,所以为了解决这个问题,您可以添加第二个窗口并将其发送到后面并使主窗口清晰,并将预览视图添加到第二个窗口dummyViewController告诉它不要通过覆盖适当的方法来自动旋转。这将允许预览不旋转,但UI可以旋转。