iOS: Capture image from front facing camera

前端 未结 5 2041
耶瑟儿~
耶瑟儿~ 2020-12-01 00:56

I am making an application where I would like to capture an image from the front facing camera, without presenting a capture screen of any kind. I want to take a picture com

5条回答
  •  情话喂你
    2020-12-01 01:18

    I converted the code above from Objc to Swift 3, if anyone still looks for a solution in 2017.

    import UIKit
    import AVFoundation
    
    class CameraViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
    
    @IBOutlet weak var cameraImageView: UIImageView!
    
    var device: AVCaptureDevice?
    var captureSession: AVCaptureSession?
    var previewLayer: AVCaptureVideoPreviewLayer?
    var cameraImage: UIImage?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        setupCamera()
        setupTimer()
    }
    
    func setupCamera() {
        let discoverySession = AVCaptureDeviceDiscoverySession(deviceTypes: [.builtInWideAngleCamera],
                                                               mediaType: AVMediaTypeVideo,
                                                               position: .front)
        device = discoverySession?.devices[0]
    
        let input: AVCaptureDeviceInput
        do {
            input = try AVCaptureDeviceInput(device: device)
        } catch {
            return
        }
    
        let output = AVCaptureVideoDataOutput()
        output.alwaysDiscardsLateVideoFrames = true
    
        let queue = DispatchQueue(label: "cameraQueue")
        output.setSampleBufferDelegate(self, queue: queue)
        output.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable: kCVPixelFormatType_32BGRA]
    
        captureSession = AVCaptureSession()
        captureSession?.addInput(input)
        captureSession?.addOutput(output)
        captureSession?.sessionPreset = AVCaptureSessionPresetPhoto
    
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
    
        previewLayer?.frame = CGRect(x: 0.0, y: 0.0, width: view.frame.width, height: view.frame.height)
    
        view.layer.insertSublayer(previewLayer!, at: 0)
    
        captureSession?.startRunning()
    }
    
    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
        let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
        CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: .allZeros))
        let baseAddress = UnsafeMutableRawPointer(CVPixelBufferGetBaseAddress(imageBuffer!))
        let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer!)
        let width = CVPixelBufferGetWidth(imageBuffer!)
        let height = CVPixelBufferGetHeight(imageBuffer!)
    
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let newContext = CGContext(data: baseAddress, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo:
            CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue)
    
        let newImage = newContext!.makeImage()
        cameraImage = UIImage(cgImage: newImage!)
    
        CVPixelBufferUnlockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: .allZeros))
    }
    
    func setupTimer() {
        _ = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(snapshot), userInfo: nil, repeats: true)
    }
    
    func snapshot() {
        print("SNAPSHOT")
        cameraImageView.image = cameraImage
    }
    }
    

    Also, I found a shorter solution for getting the image from the CMSampleBuffer:

    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
        let myPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
        let myCIimage = CIImage(cvPixelBuffer: myPixelBuffer!)
        let videoImage = UIImage(ciImage: myCIimage)
        cameraImage = videoImage
    }
    

提交回复
热议问题