-->

Getting exposure values from camera on iPhone OS 4

2019-02-25 20:39发布

问题:

Exposure values from camera can be acquired when you take picture (without saving it to SavedPhotos). A light meter application on iPhone does this, probably by using some private API.

That application does it on iPhone 3GS only, so I guess it may be somehow related to EXIF data which is populated with this information when the image is created.

This all applies to 3GS.

Has anything changed with iPhone OS 4.0? Is there a regular way to get these values now?

Does anyone have a working code example for taking these camera/photo setting values?

Thank you

回答1:

With AVFoundation in iOS 4.0 you can mess with exposure, refer specifically to AVCaptureDevice, here is a link AVCaptureDevice ref. Not sure if its exactly what you want but you can look around AVFoundation and probably find some useful stuff



回答2:

If you want realtime* exposure information, you can capture a video using AVCaptureVideoDataOutput. Each frame CMSampleBuffer is full of interesting data describing the current state of the camera.

*up to 30 fps



回答3:

I think I finally found the lead to the real EXIF data. It'll be a while before I have actual code to post, but I figured this should be publicized in the meantime.

Google captureStillImageAsynchronouslyFromConnection. It's a function of AVCaptureStillImageOutput and following is an excerpt from the documentation (long sought for):

imageDataSampleBuffer - The data that was captured. The buffer attachments may contain metadata appropriate to the image data format. For example, a buffer containing JPEG data may carry a kCGImagePropertyExifDictionary as an attachment. See ImageIO/CGImageProperties.h for a list of keys and value types.

For an example of working with AVCaptureStillImageOutput see WWDC 2010 sample code, under AVCam.

Peace, O.



回答4:

Here is the complete solution. Dont forget to import appropriate frameworks and headers. In the exifAttachments var in capturenow method you'll find all data you are looking for.

#import <AVFoundation/AVFoundation.h>
#import <ImageIO/CGImageProperties.h>

AVCaptureStillImageOutput *stillImageOutput;
AVCaptureSession *session;    

- (void)viewDidLoad
    {
        [super viewDidLoad];
        [self setupCaptureSession];
        // Do any additional setup after loading the view, typically from a nib.    
    }

    -(void)captureNow{


        AVCaptureConnection *videoConnection = nil;
        for (AVCaptureConnection *connection in stillImageOutput.connections)
        {
            for (AVCaptureInputPort *port in [connection inputPorts])
            {
                if ([[port mediaType] isEqual:AVMediaTypeVideo] )
                {
                    videoConnection = connection;
                    break;
                }
            }
            if (videoConnection) { break; }
        }

        [stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection
         completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *__strong error) {
            CFDictionaryRef exifAttachments = CMGetAttachment( imageDataSampleBuffer, kCGImagePropertyExifDictionary, NULL);
            if (exifAttachments)
            {
                // Do something with the attachments.
                NSLog(@"attachements: %@", exifAttachments);
            }
            else
              NSLog(@"no attachments");

            NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
            UIImage *image = [[UIImage alloc] initWithData:imageData];
            }];

    }


    // Create and configure a capture session and start it running
    - (void)setupCaptureSession
    {
        NSError *error = nil;

        // Create the session
        session = [[AVCaptureSession alloc] init];

        // Configure the session to produce lower resolution video frames, if your
        // processing algorithm can cope. We'll specify medium quality for the
        // chosen device.
        session.sessionPreset = AVCaptureSessionPreset352x288;

        // Find a suitable AVCaptureDevice
        AVCaptureDevice *device = [AVCaptureDevice
                                   defaultDeviceWithMediaType:AVMediaTypeVideo];
        [device lockForConfiguration:nil];

        device.whiteBalanceMode = AVCaptureWhiteBalanceModeLocked;
        device.focusMode = AVCaptureFocusModeLocked;
        [device unlockForConfiguration];

        // Create a device input with the device and add it to the session.
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
                                                                            error:&error];
        if (!input) {
            // Handling the error appropriately.
        }
        [session addInput:input];




        stillImageOutput = [AVCaptureStillImageOutput new];
        NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
        [stillImageOutput setOutputSettings:outputSettings];
        if ([session canAddOutput:stillImageOutput])
            [session addOutput:stillImageOutput];


        // Start the session running to start the flow of data
        [session startRunning];
        [self captureNow];

    }