Accessing iOS 6 new APIs for camera exposure and shutter speed

24,785

Solution 1

It's true that there is an -exposureMode property on AVCaptureDevice, but that's only for setting the mode (off/auto/continuous) and not the actual f-stop, SS, or ISO. Camera apps that provide "exposure" control all seem to do it through post-processing.

However, it seems there are undocumented APIs in the framework to do this. Check out the full headers for AVCaptureDevice.h (via a class-dump) and note the following methods:

- (void)setManualExposureSupportEnabled:(BOOL)arg1;
- (BOOL)isManualExposureSupportEnabled;

- (void)setExposureGain:(float)arg1;
- (float)exposureGain;

- (void)setExposureDuration:(struct { long long x1; int x2; unsigned int x3; long long x4; })arg1;
- (struct { long long x1; int x2; unsigned int x3; long long x4; })exposureDuration;

- (void)setExposureMode:(int)arg1;
- (int)exposureMode;

- (BOOL)isExposureModeSupported:(int)arg1;

My guess is gain is equivalent f-stop (fixed aperture), and duration is shutter speed. I wonder if these are used for the iPhone 5's low-light boost mode.

You can also use otool to poke around and try to piece together the symbols. There's likely a new constant in exposureMode for enabling manual control, and exposureDuration seems like it has flags too. When calling these, make sure to use the new -isExposureModeSupported: and also call -respondsToSelector: to check compatibility.

As always, using private APIs is frowned upon by Apple and is cause for rejection from the App Store. There might be ways around this, such as hiding the calls using -performSelector: or obc_msgsend with rot13 strings or something, as I'm pretty sure they only do static analysis on the app binary.

Solution 2

I've managed to 'trick' the camera into running a shorter exposure time, but I suspect it will only be of use to those doing similar (macro) image acquires. I first set up AVCaptureDevice to use AVCaptureExposureModeContinuousAutoExposure and set the flash to TorchMode. I then UnlockForConfiguration and set up a key-value observer to watch for adjustingExposure to finish. I then re-lock the device, flip to AVCaptureExposureModeLocked, and turn off the Torch. This has the effect of brute-force setting a shorter shutter speed than what the camera would select on the un-illuminated scene. By playing with the Torch level I can set any relative shutter speed value I want (it would be best of course to leave the torch on, but in my application it produces glare on the subject). Again this only really works when your object distance is very close (less than say 6 inches), but it's allowed me to eliminate hand shake blurring in my close-up images. The down side is that the images are darker since I don't have a way of spoofing the camera gain, but not a problem in my particular application.

Solution 3

As a follow-up to Michael Grinich's excellent information, I found that there is an order dependency on some of the calls in the private API. To use "manual" exposure controls, you have to enable them before you set the mode, like so:

#define AVCaptureExposureModeManual     3
NSError*    error = nil;
if ([captureDevice lockForConfiguration:&error]) {
    captureDevice.manualExposureSupportEnabled = YES;
    if ([captureDevice isExposureModeSupported:AVCaptureExposureModeManual]) {
        captureDevice.exposureMode = AVCaptureExposureModeManual;
        captureDevice.exposureGain = ...;
        captureDevice.exposureDuration = {...};
    }
    [captureDevice unlockForConfiguration];
}

All of this is demonstrated in iOS-ManualCamera.

Solution 4

It looks like they've updated that linked text—there's no mention of new APIs for exposure:

Use powerful new features of the built-in camera. New APIs support real-time video stabilization, an improved LED flash, and face detection and display. You can get reports of dropped frames during capture and leverage new utilities to map UI touches to focus and exposure commands. And apps that support iPhone 5 can take advantage of low light boost mode.

There is an opt-in low-light boost mode for iPhone 5, detailed here by Jim Rhoades (and in this developer forum post, log-in required).

Solution 5

Starting with iOS 8.0, this is now finally possible.

See setExposureModeCustomWithDuration etc. in the Apple documentation.

Here is an article discussing how to use the APIs.

Share:
24,785
Adam Popławski
Author by

Adam Popławski

Updated on July 09, 2022

Comments

  • Adam Popławski
    Adam Popławski almost 2 years

    On Apple's iOS 6.0 feature page, it used to say

    Take advantage of the built-in camera’s advanced features. New APIs let you control focus, exposure, and region of interest. You can also access and display faces with face detection APIs, and leverage hardware-enabled video stabilization.

    This text has since been removed, and I can't find new methods in the API for controlling exposure. In class AVCaptureDevice under "Exposure Settings" there is no new property/method for iOS 6.0. Do you know where i can find new features for exposure in API?

  • rob mayoff
    rob mayoff over 11 years
    You might also be able to use KVC (setValue:forKey:) to set those parameters without triggering the app store
  • Michael Grinich
    Michael Grinich over 11 years
    IIRC, the static analyzer looks for private class/property names, so you might need to ROT13 those strings to have them pass.
  • xissburg
    xissburg over 11 years
    I have tried to set the exposure manually with setExposureGain: and nothing changes. Also, while adjusting the exposure the exposureGain property is always 1.0. And I also called setManualExposureSupportEnabled:YES before setting the exposure. Does not work :/
  • tc.
    tc. about 11 years
    The struct appears to correspond to typedef struct {CMTimeValue; CMTimeScale;CMTimeFlags;CMTimeEpoch;} CMTime; (the members are typedefs for int64_t, int32_t, uint32_t, int64_t respectively).
  • Patricia
    Patricia over 10 years
    Is manualExposureSupportEnabled available still? I'm not seeing it.
  • Patricia
    Patricia over 10 years
    I'm trying your brute-force method but the camera is taking the picture before the torch is turned down. Any help? I have a question here: stackoverflow.com/questions/22029381/… I know the question is about both focus and exposure, but I'm just focusing on exposure for now.
  • user3115647
    user3115647 over 10 years
    I had the same problem. For some reason the torch seems to lag on for a while even after you turn it off and unlock for config. I worked around it by inserting a thread sleep of around 1 second right after the unlock. Crude I know but I could never get it to work otherwise.
  • Zhigang An
    Zhigang An about 7 years
    @tc. Confirmed. I played with this private API recently. The struct is exactly what you said.