Search code examples
iosiphoneswiftcameraavcapturesession

How to use flash to take picture on custom camera?


I've looked everywhere and I can't figure out how to toggle the flash in such a way when I take a picture it flashes 4 times like it does on the iPhone camera.

I'm using this function to toggle the flash...

func toggleFlash() {
    let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    if (device.hasTorch) {
        device.lockForConfiguration(nil)
        if (device.torchMode == AVCaptureTorchMode.On) {
            device.torchMode = AVCaptureTorchMode.Off
        } else {
            device.setTorchModeOnWithLevel(1.0, error: nil)
        }
        device.unlockForConfiguration()
    }
}

And I use this function to take a picture...

func didPressTakePhoto(){
    if let videoConnection = stillImageOutput?.connectionWithMediaType(AVMediaTypeVideo){
        videoConnection.videoOrientation = AVCaptureVideoOrientation.Portrait
        stillImageOutput?.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: {
            (sampleBuffer, error) in

            if sampleBuffer != nil {

                var imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
                var dataProvider  = CGDataProviderCreateWithCFData(imageData)
                var cgImageRef = CGImageCreateWithJPEGDataProvider(dataProvider, nil, true, kCGRenderingIntentDefault)

                var image:UIImage!

                if self.camera == true {
                    image = UIImage(CGImage: cgImageRef, scale: 1.0, orientation: UIImageOrientation.Right)

                } else {
                    image = UIImage(CGImage: cgImageRef, scale: 1.0, orientation: UIImageOrientation.LeftMirrored)

                }
                self.tempImageView.image = image
                self.tempImageView.hidden = false
            }


        })
    }


}

Solution

  • Here's a very messy way. Not clean.

    func didPressTakePhoto(){
    
    toggleFlash()
    sleep(1)
    toggleFlash()
    
    if let videoConnection = stillImageOutput?.connectionWithMediaType(AVMediaTypeVideo){
        videoConnection.videoOrientation = AVCaptureVideoOrientation.Portrait
        stillImageOutput?.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: {
            (sampleBuffer, error) in
    
            if sampleBuffer != nil {
    
                toggleFlash()
    
                var imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
                var dataProvider  = CGDataProviderCreateWithCFData(imageData)
                var cgImageRef = CGImageCreateWithJPEGDataProvider(dataProvider, nil, true, kCGRenderingIntentDefault)
    
                var image:UIImage!
                if self.camera == true {
                    image = UIImage(CGImage: cgImageRef, scale: 1.0, orientation: UIImageOrientation.Right)
    
                } else {
                    image = UIImage(CGImage: cgImageRef, scale: 1.0, orientation: UIImageOrientation.LeftMirrored)
    
                }
                self.tempImageView.image = image
                self.tempImageView.hidden = false
            }
    
    
        })
    }
    
    
    }
    

    It's very messy, just an idea. You could also use an NSTimer to fire it twice.