AVCaptureStillImageOutput&UIImagePNGRepresentation

对于我认为不应该那么困难的事情,我很难过,所以我认为我必须从错误的angular度看问题。 为了解如何AVCaptureStillImageOutput和相机工作,我做了一个小应用程序。

这个应用程序能够拍照并将其保存为PNG文件(我不需要JPEG)。 下次启动应用程序时,会检查文件是否存在,如果存在,则将存储在文件内的图像用作应用程序的背景视图。 这个想法很简单。

问题是它不起作用。 如果有人能告诉我我做错了什么,这将是非常有帮助的。

我希望图片以与显示时相同的方式出现在背景上,但是它被旋转或者尺寸错误.. ..

这里是相关的代码(如果需要,我可以提供更多的信息)。

viewDidLoad方法:

 override func viewDidLoad() { super.viewDidLoad() // For the photo capture: captureSession.sessionPreset = AVCaptureSessionPresetHigh // Select the appropriate capture devices: for device in AVCaptureDevice.devices() { // Make sure this particular device supports video. if (device.hasMediaType(AVMediaTypeVideo)) { // Finally check the position and confirm we've got the back camera. if(device.position == AVCaptureDevicePosition.Back) { captureDevice = device as? AVCaptureDevice } } } tapGesture = UITapGestureRecognizer(target: self, action: Selector("takePhoto")) self.view.addGestureRecognizer(tapGesture) let filePath = self.toolBox.getDocumentsDirectory().stringByAppendingPathComponent("BackGroundImage@2x.png") if !NSFileManager.defaultManager().fileExistsAtPath(filePath) {return} let bgImage = UIImage(contentsOfFile: filePath), bgView = UIImageView(image: bgImage) self.view.addSubview(bgView) } 

处理图片的方法:

 func takePhoto() { if !captureSession.running { beginPhotoCaptureSession() return } if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) { stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) { (imageDataSampleBuffer, error) -> Void in if error == nil { var localImage = UIImage(fromSampleBuffer: imageDataSampleBuffer) UIGraphicsBeginImageContext(localImage!.size) CGContextRotateCTM (UIGraphicsGetCurrentContext(), CGFloat(M_PI_2)) //localImage!.drawAtPoint(CGPointZero) localImage!.drawAtPoint(CGPoint(x: -localImage!.size.height, y: -localImage!.size.width)) //localImage!.drawAtPoint(CGPoint(x: -localImage!.size.width, y: -localImage!.size.height)) localImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() localImage = resizeImage(localImage!, toSize: self.view.frame.size) if let data = UIImagePNGRepresentation(localImage!) { let bitMapName = "BackGroundImage@2x" let filename = self.toolBox.getDocumentsDirectory().stringByAppendingPathComponent("\(bitMapName).png") data.writeToFile(filename, atomically: true) print("Picture saved: \(bitMapName)\n\(filename)") } } else {print("Error on taking a picture:\n\(error)")} } } captureSession.stopRunning() previewLayer!.removeFromSuperlayer() } 

启动AVCaptureSession的方法:

 func beginPhotoCaptureSession() { do {let input = try AVCaptureDeviceInput(device: captureDevice) captureSession.addInput(input) } catch let error as NSError { // Handle any errors: print(error) } previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) previewLayer?.frame = self.view.layer.frame self.view.layer.addSublayer(previewLayer!) captureSession.startRunning() stillImageOutput.outputSettings = [kCVPixelBufferPixelFormatTypeKey:Int(kCVPixelFormatType_32BGRA)] if captureSession.canAddOutput(stillImageOutput) { captureSession.addOutput(stillImageOutput) } } 

作为一个例子,这里是一个应用拍摄的照片的图像:

现在,这是我得到的应用程序的背景,当它重新启动:

如果它工作正常,2张图片将是相似的。

我不能看到在屏幕截图旋转..但规模是一个问题,这是相关的代码,当你在function takePhoto绘制它。 你可以试试

 func takePhoto() { if !captureSession.running { beginPhotoCaptureSession() return } if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) { stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) { (imageDataSampleBuffer, error) -> Void in if error == nil { if let data = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) { let bitMapName = "BackGroundImage@2x" let filename = self.toolBox.getDocumentsDirectory().stringByAppendingPathComponent("\(bitMapName).png") data.writeToFile(filename, atomically: true) print("Picture saved: \(bitMapName)\n\(filename)") } } else {print("Error on taking a picture:\n\(error)")} } } captureSession.stopRunning() previewLayer!.removeFromSuperlayer() } 

对于那些可能在同一时间点击相同问题的人,我会在代码中修改以使其工作。 支持所有可能的方向可能还需要一些改进,但是可以开始。

  if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) { stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) { (imageDataSampleBuffer, error) -> Void in if error == nil { var localImage = UIImage(fromSampleBuffer: imageDataSampleBuffer) var imageSize = CGSize(width: UIScreen.mainScreen().bounds.height * UIScreen.mainScreen().scale, height: UIScreen.mainScreen().bounds.width * UIScreen.mainScreen().scale) localImage = resizeImage(localImage!, toSize: imageSize) imageSize = CGSize(width: imageSize.height, height: imageSize.width) UIGraphicsBeginImageContext(imageSize) CGContextRotateCTM (UIGraphicsGetCurrentContext(), CGFloat(M_PI_2)) localImage!.drawAtPoint(CGPoint(x: 0.0, y: -imageSize.width)) localImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() if let data = UIImagePNGRepresentation(localImage!) { data.writeToFile(self.bmpFilePath, atomically: true) } } else {print("Error on taking a picture:\n\(error)")} } }