【问题标题】:Save what user see in AVCaptureVideoPreviewLayer保存用户在 AVCaptureVideoPreviewLayer 中看到的内容
【发布时间】:2016-10-07 10:51:00
【问题描述】:

我正在尝试开发一个带有自定义相机的应用程序,用户可以在其中添加过滤器或贴纸(如在 TextCamera 应用程序中)并在社交信息流中分享。 但是我发现了我的第一个问题。

我使用 AVCaptureVideoPreviewLayer 向用户显示预览,拍摄照片并将其传递给 UiImageView 中的另一个视图控制器,但第二张图片比第一张大。

我尝试用这个函数调整图片大小:

    func resize(image: UIImage) -> UIImage {
       let size = image.size
       let newWidth = CGFloat(size.width)
       let newHeight = CGFloat(size.height - blackBottomTab.bounds.size.height)

       let newSize = CGSizeMake(newWidth,newHeight)
       let rect = CGRectMake(0, 0, newSize.width, newSize.height)

       UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
       image.drawInRect(rect)
       let newImage = UIGraphicsGetImageFromCurrentImageContext()
       UIGraphicsEndImageContext()

       return newImage
}

在这个函数中,我从图像高度中减去黑色视图(按钮下方)的高度。但是我得到的结果是不同的(见附图)。

This is my preview with a black view under the button

This is the photo taken larger than preview one

我也尝试在第二个 View Controller 的 Storyboard Image View 中使用 Aspect Fit,但结果是一样的。

我的错误在哪里?感谢所有帮助过我的人!

【问题讨论】:

    标签: ios swift avfoundation


    【解决方案1】:

    我认为AVCaptureVideoPreviewLayer 框架与屏幕的框架 (UIScreen.mainScreen().bounds) 相同,并且您在其顶部添加了“Shoot Photo”黑色视图。相反,您应该更改AVCaptureVideoPreviewLayer 的框架。

    你的情况(我的想法):

    假设绿色矩形是AVCaptureVideoPreviewLayer 框架,红色矩形是黑色视图框架。因此,它覆盖了绿色矩形的(顶部)。

    让它们看起来像这样:

    希望有所帮助。

    【讨论】:

    • 这是解决方案吗? :) 如果不是,请发表评论
    • 不,Ahmad,我的故事板中也有这个配置。 :(
    • 您能否提供代码来说明您如何初始化和设置 AVCaptureVideoPreviewLayer?
    • func setupPreview() { // 配置 previewLayer previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) previewLayer.frame = cameraPreview.bounds previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill cameraPreview.layer.addSublayer(previewLayer) }
    • 那么,cameraPreview.bounds 不等于屏幕大小对吧?你在哪里调用“setupPreview()”?在 viewDidLoad 中?
    【解决方案2】:

    我不得不解决一个类似的问题。正如问题所指出的,似乎没有一种简单的方法可以检测视频预览的大小。

    https://stackoverflow.com/a/57996039/10449843 的答案末尾暗示了我的解决方案,其中详细解释了我如何拍摄快照并使用贴纸创建组合快照。

    这里是该提示的详细说明。

    虽然我使用 AVCapturePhotoCaptureDelegate 拍摄快照,但我还使用 AVCaptureVideoDataOutputSampleBufferDelegate 在第一次显示预览时对缓冲区进行采样以检测快照的比例。

                // The preview layer is displayed with aspect fill
                let previewLayer = AVCaptureVideoPreviewLayer(session: session)
                previewLayer.videoGravity = .resizeAspect
                previewLayer.frame = self.cameraView.bounds
    

    检测预览的大小:

    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
            // Only need to do this once
            guard self.sampleVideoSize == true else {
                return
            }
    
            guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
                return
            }
    
            // Sample the size of the preview layer and then store it
            DispatchQueue.main.async {
    
                let width = CGFloat(CVPixelBufferGetWidth(pixelBuffer))
                let height = CGFloat(CVPixelBufferGetHeight(pixelBuffer))
    
                // Store the video size in a local variable
                // We don't care which side is which, we just need the
                // picture ratio to decide how to align it on different
                // screens.
                self.videoSize = CGSize.init(width: width, height: height)
    
                // Now we can set up filters and stickers etc
                ...
    
                // And we don't need to sample the size again
                self.sampleVideoSize = false
            }
            return
        }
    

    【讨论】:

    • 有趣,但这个指的是另一个答案,也指另一个答案......相当迷失,因为相应的问题有多个答案得到很好的评价......我的问题是我有一个正方形(1 :1) AVCaptureVideoPreviewLayer,我得到的图片是 1080x1920,但我只想要这张图片的方形裁剪(只有用户看到的)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多