0%

捕获静态图片

本文将为Kcamera增加拍摄相片的功能.Kcamera的代码可以在https://github.com/changjianfeishui/Kcamera上找到.

实现步骤

初始化AVCaptureStillImageOutput对象

打开CaptureModel类,增加一个属性:

//AVCaptureOutput子类,用于捕捉静态图片
var imageOutput:AVCaptureStillImageOutput!

在setupSession()方法最后return之前添加如下代码:

   //7. 创建图片输出对象并添加到捕捉会话中
   self.imageOutput = AVCaptureStillImageOutput()
   self.imageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]
   if self.captureSession .canAddOutput(self.imageOutput) {
       self.captureSession.addOutput(self.imageOutput)
   }
   	   
   

拍摄静态图片

在setupSession()方法中,我们将一个AVCaptureStillImageOutput实例添加到了捕捉会话中.这个类是AVCaptureOutput的子类,用于捕捉静态图片.其outputSettings属性可用来配置要捕捉的图片.

AVCaptureStillImageOutput类定义了captureStillImageAsynchronouslyFromConnection()方法来执行实际的拍摄.

//捕捉静态图片
func captureStillImage() -> Void {
    //1. 建立输入和输出的连接
    let connection = self.imageOutput.connectionWithMediaType(AVMediaTypeVideo)
    //2. 设置照片方向
    if connection.supportsVideoOrientation {
        connection.videoOrientation = self.currentVideoOrientation()
    }
    
    //3. 拍摄照片        
    self.imageOutput.captureStillImageAsynchronouslyFromConnection(connection) { (sampleBuffer, error) in
        if sampleBuffer != nil{
            let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
            let image = UIImage(data: imageData)
        }else{
            print(error.localizedDescription)
        }
    }
}  

其中currentVideoOrientation()方法的实现如下:

//获取当前视频方向
func currentVideoOrientation() -> AVCaptureVideoOrientation {
    var orientation:AVCaptureVideoOrientation!
    switch UIDevice.currentDevice().orientation {
    case .Portrait:
        orientation = .Portrait
    case .LandscapeRight:
        orientation = .LandscapeRight
    case .PortraitUpsideDown:
        orientation = .PortraitUpsideDown
    case .LandscapeLeft:
        orientation = .LandscapeLeft
    default:
        orientation = .Portrait
    }
    return orientation
}    

存储图片到相册

在获取到拍摄图片输出对象的sampleBuffer并将其转化为UIImage对象后,就可以将其写入到系统相册中了.

在获取到转换的UIImage对象后增加如下代码:

//4. 写入照片
self.writeImageToAssetsLibrary(image!)

并实现writeImageToAssetsLibrary()方法如下:

//将捕捉到的图片写入到相册
func writeImageToAssetsLibrary(image:UIImage) -> Void {
    //1. 判断相册访问权限
    let authStatus = ALAssetsLibrary.authorizationStatus()
    if authStatus == .Denied || authStatus == .Restricted {
        UIAlertView(title: "提示", message: "请打开相册访问权限", delegate: nil, cancelButtonTitle: "确定").show()
        return
    }
    
    //2. 存储图片
    let library = ALAssetsLibrary()
    let orientation = ALAssetOrientation(rawValue: image.imageOrientation.rawValue)
    library.writeImageToSavedPhotosAlbum(image.CGImage, orientation: orientation!) { (assetURL, error) in
        if error != nil{
            print(error.localizedDescription)
        }
    }
}	   

测试

打开ViewController类,找到captureBtnDidClicked()方法,将其修改为:

@IBAction func captureBtnDidClicked(sender: CaptureButton) {
    if self.cameraModel == CameraModel.Video{
        sender.selected = !sender.selected
    }else{
        self.captureModel.captureStillImage()
    }
}

编译运行程序,切换到Photo模式,点击拍摄按钮.然后在系统相册中查看拍摄的照片.