AVCaptureVideoPreviewLayer并从相机位置预览

时间:2015-02-12 14:44:24

标签: swift sdk ios8 avcapture

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

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 个答案:

答案 0 :(得分:9)

首先获取屏幕尺寸,以便计算宽高比

    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)

    }

这可能需要一些调整,因为我还没有对它进行现场测试,但你应该能够创建一个更灵活的VideoPreviewArea,它由你的APPreviewView界限界定。

答案 1 :(得分:1)

您所看到的不是图层的位置,因为视图/图层的方面与相机的纵横比不匹配,所以它的位置不同使用videoGravity属性和方面填充它(总是暗示居中)

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

答案 2 :(得分:0)

我遇到了这个问题,即使代码工作,提供的代码也没有解决问题。我一直在使用界面构建器构建我的应用程序。

在属性检查器中,在扩展边缘下面有一些设置,所有视图都要在顶部栏和底栏下方展开。我的设置检查了这些,这是为了放弃视图定位的计算。

utilities navigator

扩展边缘设置:

extend edges settings

答案 3 :(得分:0)

我有一个类似的问题,我解决了这个问题:

 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.addSubview(previewLayer)
                //                previewLayer.
                videoLayer.layer.addSublayer(previewLayer)
                captureSession.startRunning()

希望这有助于:)