Filip Filip - 1 year ago 67
Objective-C Question

Leveling and matching exposure using CoreImage / GPUImage

I was wondering if its possible to level exposure across a set of images using either

. And how would I go about that?

Say you have 4 images, but the exposure is different on the third one. How could you level the exposure so all 4 images have the same exposure?

One idea I had was measuring and matching the exposure using
, i.e. if the input image is -2.0, then simply add 2.0 using

Another idea is to implement histogram equalization..

Has anyone ever dealt with the same task before? Any insights?

Answer Source

You can use CoreImage (#import ) and ImageIO (CGImage) and extract exif metadata with EXIF Dictionary Keys keys:kCGImagePropertyExifExposureTime, kCGImagePropertyExifExposureMode, kCGImagePropertyExifExposureProgram, kCGImagePropertyExifExposureBiasValue, kCGImagePropertyExifExposureIndex, kCGImagePropertyExifWhiteBalance

- (NSDictionary*) exifData: (NSString*) path {  

NSDictionary* dic   =   nil;
NSURL* url          =   [NSURL fileURLWithPath: path];  

if ( url )  
    CGImageSourceRef source = CGImageSourceCreateWithURL ((CFURLRef) url, NULL);

    if (source != nil)
        CFDictionaryRef metadataRef = 
        CGImageSourceCopyPropertiesAtIndex (source, 0, NULL);  
        if (metadataRef)   
            NSDictionary* immutableMetadata = (NSDictionary *)metadataRef;  
            if (immutableMetadata)
                dic = [NSDictionary dictionaryWithDictionary : (NSDictionary *)metadataRef];
            CFRelease ( metadataRef );
        source = nil;  

return dic;


NSDictionary* dic = [self exifData: path];  
if (dic)
    NSString *s = [dic valueForKey: kCGImagePropertyExifExposureTime];  
    NSLog(@"Image : %@ - ExposureTime : %.2f", path, [s floatValue]);  

And then changing the exposure or white balance with:

- (UIImage *) changeImageExposure:(NSString*) imagename exposure:(float) exposure {  
   CIImage *inputImage = [[CIImage alloc] initWithImage:[UIImage imageNamed: imagename]];
   CIFilter *exposureAdjustmentFilter = [CIFilter filterWithName:@"CIExposureAdjust"];
   [exposureAdjustmentFilter setValue:inputImage forKey:kCIInputImageKey];
   [exposureAdjustmentFilter setValue:[NSNumber numberWithFloat:exposure] forKey:@"inputEV"];
   CIImage *outputImage = exposureAdjustmentFilter.outputImage;
   CIContext *context = [CIContext contextWithOptions:nil];
   return [UIImage imageWithCGImage:[context createCGImage:outputImage fromRect:outputImage.extent]];