Last Updated: February 25, 2016
·
2.109K
· mxcl

[UIImage preferredStatusBarStyle]

If you have an image directly under your StatusBar (without a NavigationBar under it) then you should have the preferredStatusBar for that ViewController update to reflect the average color value for that image.

ie. a dark image should have white text and a light image black text.

@interface UIImage (mxcl)
@end

@implementation UIImage (mxcl)

- (UIStatusBarStyle)preferredStatusBarStyle {
    UIGraphicsBeginImageContextWithOptions((CGSize){1, 1}, NO, 0.0);
    [self drawInRect:(CGRect){0, 0, 1, 1}];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    BOOL imageIsLight = NO;

    CGImageRef imageRef = [img CGImage];
    CGDataProviderRef dataProviderRef = CGImageGetDataProvider(imageRef);
    NSData *pixelData = (__bridge_transfer NSData *)CGDataProviderCopyData(dataProviderRef);

    if ([pixelData length] > 0) {
        const UInt8 *pixelBytes = [pixelData bytes];

        // Whether or not the image format is opaque, the first byte is always the alpha component, followed by RGB.
        uint8_t pixelR = pixelBytes[1];
        uint8_t pixelG = pixelBytes[2];
        uint8_t pixelB = pixelBytes[3];

        // Calculate the perceived luminance of the pixel; the human eye favors green, followed by red, then blue.
        double percievedLuminance = 1 - (((0.299 * pixelR) + (0.587 * pixelG) + (0.114 * pixelB)) / 255);

        imageIsLight = percievedLuminance < 0.5;
    }

    return imageIsLight ? UIStatusBarStyleDefault : UIStatusBarStyleLightContent;
}

@end

Code mostly stolen from Path’s FICImageCacheDemo project.