2017-03-09 51 views
1

我想保存顯示相機視圖(AVCapturePhotoOutput)的屏幕截圖。無法獲取在Swift中顯示相機(AVCapturePhotoOutput)的UIView的屏幕截圖

我設置了cameraView(顯示相機視圖)並添加了其他UIView,如UIButton的一些部分。

但是,如果我保存它,保存到相機膠捲的圖片只是一個白色的視圖。 (當我試圖保存self.view的截圖時,它確實工作正常。)

我該如何解決它?

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'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<UITouch>, 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); 

     } 
} 

UPDATE:製作CAShapeLayer的

添加的代碼,但它不能顯示攝像機視圖,並完成保存圖像時,圖像只有白色畫面....

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); 
+0

試試這個http://stackoverflow.com/a/42668262/5461400 –

+0

它沒有很好地工作。我更新了我的代碼,請檢查它。 – bao

+0

你不需要掩飾。剛剛從當前上下文中獲取圖像 –

回答

0

從捕獲會話圖片

let stillImageOutput = AVCaptureStillImageOutput() 

stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG] 
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!) 
    }) 
} 

卵石UIView的

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

AVCapturePhotoCaptureDelegate

集委託nshot自我

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) 
    } 

} 
+0

錯誤「Value of type」AVCapturePhotoOutput「has no member」captureStillImageAsynchronously「has been on the line」output?.captureStillImageAsynchronously ...「...(我設置了」AVCapturePhotoCaptureDelegate「第一個) – bao

+0

var輸出:AVCaptureStillImageOutput?不AVCapturePhotoOutput –

+0

檢查更新的答案 –