The camera preview looks perfect, but when I take a picture and save it to the Camera Roll the picture comes out extremely dark. Tried a bunch of threads on here but nothing solved it. Here's my code.
This sets up the camera/preview and works fine:
captureSession.sessionPreset = AVCaptureSessionPreset640x480
let devices = AVCaptureDevice.devices()
// Loop through all the capture devices on this phone
for device in 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
}
}
}
if captureDevice != nil {
beginSession()
}
func beginSession() {
var err : NSError? = nil
if captureSession.canAddInput(AVCaptureDeviceInput(device: captureDevice, error: &err)) {
captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &err))
if err != nil {
println("error: \(err?.localizedDescription)")
}
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
self.view.layer.addSublayer(previewLayer)
self.view.bringSubviewToFront(cameraButton)
previewLayer?.frame = self.view.layer.frame
// start camera
captureSession.startRunning()
}
This is called when the picture is taken:
@IBAction func photoTaken(sender: UIButton) {
stillImageOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
if captureSession.canAddOutput(stillImageOutput) {
captureSession.addOutput(stillImageOutput)
}
var videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo)
if videoConnection != nil {
// Show next step button
self.view.bringSubviewToFront(self.nextStep)
self.nextStep.hidden = false
// Secure image
stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) {
(imageDataSampleBuffer, error) -> Void in
var imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
self.image = UIImage(data: imageData)
}
// Freeze camera preview
captureSession.stopRunning()
}
}
This is called after the picture is taken when the user hits the button to proceed (it saves the image to the camera roll for now, but will eventually do more when I get the images to look good):
@IBAction func nextStepTapped(sender: UIButton) {
// Save to camera roll & proceeed
UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil)
}
My guess is that the issue is within the photoTaken() function, but I have no idea. This is my first time writing an app in Swift/Xcode, so any help would greatly be appreciated. Again, the issue is that the saved photo is extremely dark and I've tried pretty much everything I could find on the internet related to this problem, but nothing works. Thanks!
Edit: Might be worth noting that I'm testing this on an iPhone 4S. Could that have anything to do with it?
First, you need to tap to set focus on your subject. Then, simply swipe up or down on the screen to adjust exposure. Swipe up to make the image brighter. Or swipe down to make it darker.
Dark images happen when the shutter speed is too fast or the aperture isn't open enough. Be careful of your camera's automatic settings. Most cameras tend not to pick the right ones by default. If your camera creates an image that is too dark, use EV to bump up the brightness.
The issue was that I was calling this as the photo was being taken:
stillImageOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
if captureSession.canAddOutput(stillImageOutput) {
captureSession.addOutput(stillImageOutput)
}
I moved that section from photoTaken() (called when a picture is taken) to beginSession() (called to initiate the camera) and now it works. Setting up the output after the photo button was pressed probably caused a lag/delay and didn't enable the camera to fully go through the motions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With