Search code examples
objective-cios4uiimagecgcontextuicolor

Get stand out color of UIImage


I'm trying to get the color that stands out in a uiimage like I would get a red color if this was the photo: Red Color

I know to get the average color i would use the code below but it would return nlack or a gray as the average color I want this code to get that red color.

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        unsigned char rgba[4];
        CGContextRef context = CGBitmapContextCreate(rgba, 1, 1, 8, 4, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

        CGContextDrawImage(context, CGRectMake(0, 0, 1, 1),  artworkImageView.image.CGImage);
        CGColorSpaceRelease(colorSpace);
        CGContextRelease(context);
        UIColor *colorOfArtwork;

         if(rgba[3]) {
            CGFloat alpha = ((CGFloat)rgba[3])/255.0;
            CGFloat multiplier = alpha/255.0;
            colorOfArtwork = [UIColor colorWithRed:((CGFloat)rgba[0])*multiplier
                                   green:((CGFloat)rgba[1])*multiplier
                                    blue:((CGFloat)rgba[2])*multiplier
                                   alpha:alpha];
        }
        else {
            colorOfArtwork =  [UIColor colorWithRed:((CGFloat)rgba[0])/255.0
                                   green:((CGFloat)rgba[1])/255.0
                                    blue:((CGFloat)rgba[2])/255.0
                                   alpha:((CGFloat)rgba[3])/255.0];
        }

Solution

  • I did something very similar to omz's answer.

    1). Iterate through pixels and capture the most frequent colors in a UIImage

    2). Iterate over the most frequent colors and find the color that has the highest (value + saturation) sum.

    I found out that value(brightness) plus the saturation would work when I visited http://colorizer.org . A saturation of 0 is white and a value of 0 is black. Opposite of these colors I noticed that at around 100% saturation and value is where these stand out colors subsided.

    Another option which I tried but returned less favorable results, was to convert it to HSL and retrieve the lightness. In a range from 0 - 100, 50 is where the saturation and value would be 100. So instead of getting the highest sum of saturation and value you would iterate through the colors getting the color with a lightness most close to 50.

    My code is below:

    #import "ImageHelper.h" //Found Here-> https://github.com/fylfot/MostResentColorUIImage/blob/master/MostRecentColor/ImageHelper.h
    
    ...
    
    float maxDominatingFactor = 0.0;
    UIColor *standOutColor;
    NSArray *colors = [ImageHelper mostFrequentColors:30 of:self withColorPallete:ColorPalete512];
    for(UIColor *color in colors){
        if(([color brightness] + [color saturation]) > maxDominatingFactor){
            standOutColor = color;
            maxDominatingFactor = ([color brightness] + [color saturation]);
        }
    }
    
    //standOutColor is now the stand out color
    

    Note: I have a category on UIColor for calculating brightness and saturation.

    Here is a project I made for it:

    https://github.com/kdogisthebest/StandOutColor