菜鸟教程小白 发表于 2022-12-11 19:11:00

ios - 无法仅在 Swift 中显示相机(AVCapturePhotoOutput)的 UIView 的屏幕截图


                                            <p><p>我想保存显示相机 View 的屏幕截图 (AVCapturePhotoOutput)。</p>

<p>我设置了cameraView(显示相机 View )并添加了其他具有UIButton等部分的UIView。</p>

<p>但是如果我保存它,保存到相机胶卷的图片只是一个白色 View 。
(当我尝试保存 self.view 的屏幕截图时,效果很好。)</p>

<p>我该如何解决?</p>

<pre><code>class ViewController: UIViewController, AVCapturePhotoCaptureDelegate{

    //for camera
    var captureDevice : AVCaptureDevice!
    var captureSesssion: AVCaptureSession!
    var stillImageOutput: AVCapturePhotoOutput?
    var previewLayer: AVCaptureVideoPreviewLayer?
    var videoConnection:AVCaptureConnection!

    var topView: TopView! //on cameraView. It has some buttons and imageViews.
    var cameraView:UIView! //that shows camera&#39;s view

    override func viewDidLoad() {
      super.viewDidLoad()

      self.view.backgroundColor = (UIColor.black)

      cameraView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: self.view.frame.size.height))
      self.view.addSubview(cameraView)

      captureSesssion = AVCaptureSession()
      stillImageOutput = AVCapturePhotoOutput()

      captureSesssion.sessionPreset = AVCaptureSessionPreset1280x720
      captureDevice = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .front)

      do {
            let input = try AVCaptureDeviceInput(device: captureDevice)

            if (captureSesssion.canAddInput(input)) {
                captureSesssion.addInput(input)

                if (captureSesssion.canAddOutput(stillImageOutput)) {
                  captureSesssion.addOutput(stillImageOutput)
                  captureSesssion.startRunning()

                  previewLayer = AVCaptureVideoPreviewLayer(session: captureSesssion)
                  previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect
                  previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
                  previewLayer?.connection.automaticallyAdjustsVideoMirroring = false
                  previewLayer?.connection.isVideoMirrored = true
                  cameraView.layer.addSublayer(previewLayer!)

                  previewLayer?.position = CGPoint(x: self.view.frame.width / 2, y: self.view.frame.height / 2)
                  previewLayer?.bounds = self.view.frame
                }
            }
      }
      catch {
            print(error)
      }

      topView = TopView.init(frame: CGRect(x: 0, y: 0, width: 320, height: 568))
      topView.viewController = self
      self.view.addSubview(topView)

    }

    override func touchesBegan(_ touches: Set&lt;UITouch&gt;, with event: UIEvent?) {

      let touch = touches.first!
      captureSesssion.stopRunning() //for taking still picture
      let layer = UIApplication.shared.keyWindow?.layer
      let scale = UIScreen.main.scale
      UIGraphicsBeginImageContextWithOptions((layer?.frame.size)!, false, scale);

      cameraView.layer.render(in: UIGraphicsGetCurrentContext()!)
      let screenshot = UIGraphicsGetImageFromCurrentImageContext()
      UIGraphicsEndImageContext()

      //save the screenshot to camera roll      
      UIImageWriteToSavedPhotosAlbum(screenshot!, nil, nil, nil);

      }
}
</code></pre>

<p><strong>更新:</strong></p>

<p>增加了制作CAShapeLayer的代码,但是无法显示相机 View ,保存图片后,图片只是白色的图片......</p>

<pre><code>cameraView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: self.view.frame.size.height))
self.view.addSubview(cameraView)

let cropRectOverlay = CAShapeLayer() //added
cameraView.layer.mask = cropRectOverlay //added
cameraView.layer.addSublayer(cropRectOverlay) //added
...
previewLayer?.connection.automaticallyAdjustsVideoMirroring = false
previewLayer?.connection.isVideoMirrored = true
cameraView.layer.addSublayer(cropRectOverlay) //added
...

UIGraphicsBeginImageContextWithOptions(cameraView.bounds.size, false, 0); //added
cameraView.layer.render(in: UIGraphicsGetCurrentContext()!) //added
let image = UIGraphicsGetImageFromCurrentImageContext(); //added
UIGraphicsEndImageContext(); //added

//When added resultImageView, it shows black view.         
//let resultImageView = UIImageView(frame: self.view.frame)
//resultImageView.image = image
//self.view.addSubview(resultImageView)

UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil);
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>来自捕获 session 的图像</p>

<pre><code>let stillImageOutput = AVCaptureStillImageOutput()

stillImageOutput.outputSettings =
if captureSession.canAddOutput(stillImageOutput) {
      captureSession.addOutput(stillImageOutput)
}


func captureImage() {
   let videoConnection = stillImageOutput.connection(withMediaType: AVMediaTypeVideo)
   stillImageOutput.captureStillImageAsynchronously(from: videoConnection, completionHandler: {(ingDataBuffer, error) in
         let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(ingDataBuffer)
         self.imgView.image = UIImage(data: imageData!)
    })
}
</code></pre>

<p>UIView 截图</p>

<pre><code>UIGraphicsBeginImageContextWithOptions(cameraView.bounds.size, false, 0);
cameraView.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
</code></pre>

<p>AVCapturePhotoCaptureDelegate </p>

<p>将委托(delegate)设置为自己</p>

<pre><code>func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: NSError?) {

    if let sampleBuffer = photoSampleBuffer, let previewBuffer = previewPhotoSampleBuffer, let dataImage = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: sampleBuffer, previewPhotoSampleBuffer: previewBuffer) {
      print(image: UIImage(data: dataImage).size)
    }

}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 无法仅在 Swift 中显示相机(AVCapturePhotoOutput)的 UIView 的屏幕截图,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/42687723/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/42687723/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 无法仅在 Swift 中显示相机(AVCapturePhotoOutput)的 UIView 的屏幕截图