无法仅获取在 Swift 中显示相机(AVCapturePhotoOutput)的 UIView 的屏幕截图
Posted
技术标签:
【中文标题】无法仅获取在 Swift 中显示相机(AVCapturePhotoOutput)的 UIView 的屏幕截图【英文标题】:Can't get screenshot of only the UIView which shows camera (AVCapturePhotoOutput) in Swift 【发布时间】:2017-03-09 05:50:58 【问题描述】:我想保存显示相机视图的屏幕截图 (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);
【问题讨论】:
试试这个***.com/a/42668262/5461400 效果不佳。我更新了我的代码,所以请检查一下。 你不需要屏蔽。只需从当前上下文中获取图像 【参考方案1】:来自捕获会话的图像
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)
【讨论】:
错误“类型“AVCapturePhotoOutput”的值没有成员“captureStillImageAsynchronously”已在“输出?.captureStillImageAsynchronously...”行上引起......(我首先设置了“AVCapturePhotoCaptureDelegate”) var 输出:AVCaptureStillImageOutput?不是 AVCapturePhotoOutput以上是关于无法仅获取在 Swift 中显示相机(AVCapturePhotoOutput)的 UIView 的屏幕截图的主要内容,如果未能解决你的问题,请参考以下文章
如何仅在 Swift 中访问从相机拍摄的图像,就像 iOS 中的画廊一样?