代码之家  ›  专栏  ›  技术社区  ›  Tiziano

AVCaptureVideoPreviewLayer和从相机位置预览

  •  2
  • Tiziano  · 技术社区  · 11 年前

    我正在开发一个允许用户拍照的应用程序。 我已经开始使用 AVCam 苹果提供,但我实际上有问题 简单地说,我无法将相机层定位在我想要的位置,但它会自动定位在视图的中心

    enter image description here

    在左边,你可以看到我实际拥有的,在右边,我想要拥有的。 包含来自相机的预览的视图是 UIView 子类,这是代码

    class AVPreviewView : UIView {
        override class func layerClass() -> AnyClass {
            return AVCaptureVideoPreviewLayer.self
        }
        func session () -> AVCaptureSession {
            return (self.layer as AVCaptureVideoPreviewLayer).session
        }
    
        func setSession(session : AVCaptureSession) -> Void {
            (self.layer as AVCaptureVideoPreviewLayer).session = session;
            (self.layer as AVCaptureVideoPreviewLayer).videoGravity = AVLayerVideoGravityResizeAspect;
    
        }
    }
    

    感谢任何帮助

    4 回复  |  直到 11 年前
        1
  •  11
  •   kellanburket    11 年前

    首先获取屏幕大小,以便计算纵横比

        let screenWidth = UIScreen.mainScreen().bounds.size.width
        let screenHeight = UIScreen.mainScreen().bounds.size.height
        var aspectRatio: CGFloat = 1.0
    
        var viewFinderHeight: CGFloat = 0.0
        var viewFinderWidth: CGFloat = 0.0
        var viewFinderMarginLeft: CGFloat = 0.0
        var viewFinderMarginTop: CGFlaot = 0.0
    

    现在计算预览层的大小。

        func setSession(session : AVCaptureSession) -> Void {
    
            if screenWidth > screenHeight {
                aspectRatio = screenHeight / screenWidth * aspectRatio
                viewFinderWidth = self.bounds.width
                viewFinderHeight = self.bounds.height * aspectRatio
                viewFinderMarginTop *= aspectRatio
            } else {
                aspectRatio = screenWidth / screenHeight
                viewFinderWidth = self.bounds.width * aspectRatio
                viewFinderHeight = self.bounds.height
                viewFinderMarginLeft *= aspectRatio
            }
    
            (self.layer as AVCaptureVideoPreviewLayer).session = session;
    

    设置图层的 videoGravity AVLayerVideoGravityResizeAspectFill 这样,在给定自定义视图的情况下,层将拉伸以填充。

            (self.layer as AVCaptureVideoPreviewLayer).videoGravity = AVLayerVideoGravityResizeAspectFill;
    

    最后,将预览层的框架设置为上面计算的值,并使用您喜欢的任何偏移。

            (self.layer as AVCaptureVideoPreviewLayer).frame = CGRectMake(viewFinderMarginLeft, viewFinderMarginTop, viewFinderWidth, viewFinderHeight)
    
        }
    

    这可能需要一些调整,因为我还没有对其进行实时测试,但您应该能够创建一个由APPreviewView边界分隔的更灵活的VideoPreviewArea。

        2
  •  3
  •   David Berry    11 年前

    您看到的不是层的位置,而是视图/层的纵横比与相机的纵横比不匹配,因此它使用 videoGravity 填充它的属性和方面(总是意味着居中)

    创建图层时,调整其大小以使纵横比正确,然后随意定位。或者,在这种情况下,将视图调整到正确的纵横比,然后可以随意定位视图。

        3
  •  2
  •   spacecash21    5 年前

    我有一个类似的问题,我通过这样做来解决:

     previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
                    previewLayer.anchorPoint = videoLayer.bounds.origin
                    previewLayer.frame = CGRect(x: videoLayer.bounds.origin.x, y: videoLayer.bounds.origin.y, width: videoLayer.frame.size.width, height: videoLayer.frame.size.height)
                    videoLayer.layer.addSublayer(previewLayer)
                    captureSession.startRunning()
    

    希望这能有所帮助:)

        4
  •  1
  •   Rick Smith Robert Truitt    9 年前

    我遇到了这个问题,尽管代码有效,但提供的代码并没有解决这个问题。我一直在使用界面生成器构建我的应用程序。

    在属性检查器中,延伸边下有一些设置,所有视图都将在顶部栏和底部栏下延伸。我的设置进行了检查,这会影响视图定位的计算。

    utilities navigator

    延伸边设置:

    extend edges settings