我想保存显示相机视图的截图(AVCapturePhotoOutput)。
我设置了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);
}
}
更新
添加制作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 :(得分: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
将委托设置为自我
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)
}
}