【发布时间】:2016-01-08 10:34:53
【问题描述】:
我在做一些我认为不应该那么困难的事情时遇到了困难,所以我想我一定是从错误的角度看待问题。 为了了解 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)
}
}
作为一个例子,这里是一张使用应用程序拍摄的照片:
现在这是我重新启动应用程序时得到的背景:
如果工作正常,两张图片会很相似。
【问题讨论】:
-
“问题是它不起作用。”嗯,这是什么意思?
-
这意味着它没有做我想要的。这在以下句子中进行了解释:“我希望图片以与拍摄时在显示屏上相同的方式显示为背景”。
-
好的,但是你还没有说它在做什么(屏幕截图、崩溃信息等)。见How to Ask 和minimal reproducible example
-
它没有崩溃,应用程序在技术上可以正常工作,但我得到的背景不是我想要的。如果有帮助,我可以提供 2 个屏幕截图。
-
我添加了两张截图,以清楚地显示我想要的和我得到的之间的区别。
标签: ios swift avcapture uiimagepngrepresentation avcaptureoutput