Disabling tone mapping in iOS camera AVCaptureDevice

I'm trying to make an iOS app where the user can adjust the exposure manually (I'm using a single slider to adjust ISO and shutter speed at the same time). It mostly works fine, however when I adjust these values, I can tell iOS is doing an additional tone mapping step to try to equalize the pixel values, and it messes with the exposure (for example, really brightening up dark pixels when I might actually want them dark). I've tried everything I can see in the documentation to disable this extra tone mapping step, but none of these successfully disable it (I'm testing using an iPhone 8 with iOS 13.3.1). Any ideas what else I can do to disable this effect and get unmodified pixels?


camera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back)

if (camera.isLowLightBoostSupported)
  {
       camera.automaticallyEnablesLowLightBoostWhenAvailable = false;
  }
if (camera.activeFormat.isGlobalToneMappingSupported)
  {
       camera.isGlobalToneMappingEnabled = false;
  }
camera.automaticallyAdjustsVideoHDREnabled = false;
if (camera.activeFormat.isVideoHDRSupported)
  {
       camera.isVideoHDREnabled = false;
  }

Replies

Hi there. Though it may seem counter-intuitive, setting global tone mapping to false is the opposite of what you want to do. Global tone mapping is off by default, and instead local tone mapping is used to constantly adjust the tone curves to adapt to changing scene dynamics. In order to get the most stable manual control, you want to turn global tone mapping on, and then use the manual exposure API to adjust the ISO and shutter speed to your liking.

Ah, well that I would not have guessed, thanks! However, while it works the first time I call it, if I try going back to auto exposure (with the following code):


  camera.exposureMode = .continuousAutoExposure;
  camera.isSubjectAreaChangeMonitoringEnabled = true;
  camera.setExposureTargetBias(0, completionHandler: nil);
  if (camera.activeFormat.isGlobalToneMappingSupported)
  {
       camera.isGlobalToneMappingEnabled = false; // enables local tone mapping
  }


and then go back to my custom exposure mode (setting isSubjectAreaChangeMonitoringEnabled to false and calling camera.setExposureModeCustom(...), plus setting camera.isGlobalToneMappingEnabled to true again), the unwanted tone mapping returns (i.e. isn't diabled by setting camera.isGlobalToneMappingEnabled to true). Any ideas why it would work on the first call but not on subsequent calls? Is it just buggy?

Could be an ordering issue. You should know that most exposure properties act as modifiers to the main -exposureMode setter. Thus you should set all the properties, then camera.exposureMode = .continuousAutoExposure _last_. Setting the exposureMode property will take all other modifiers into account as the device atomically goes into continuousAutoExposure mode and applies all the modifier state.


If after trying out these fixes, things are still not working, please file a bug at let us know here the bug number. It's always best to include a little sample app that reproduces the problem.

I've been told that Tone-Mapping can NOT be turned off on iPhone IOS devices. Is there an App that you may know of now, that does allow for us to be able to turn it off with video, so that when we can control exposure by locking it in with say Filmic Pro, that the tone-mapping doesn't still over-ride and mess with exposure adjustments? It is something that can be disabled with Android phones I've learned. As a result, too much adjustment happens, when in a brightly lit room, one moves with their camera while recording video, due to the tone-mapping creating havoc, when you thought you've locked in your exposure. Are there any plans to give us this control of "Tone-Mapping" either with-in the IOS settings for our camera or is there an "App" that you know of, that gives us this control now? These cameras have come a long way but this inability to control the "Tone-Mapping" function, still is One Pro function we need control over. Thanks!