How to get inverse color from UIColor?

Mr. Ming picture Mr. Ming · May 5, 2011 · Viewed 14.5k times · Source

e.g. The inverse color from black should be white.

Answer

Mr. Ming picture Mr. Ming · May 5, 2011

---- EDIT ----

Based on @amleszk's answer, I updated the UIColor extension/category with this method:

Swift

func inverseColor() -> UIColor {
    var alpha: CGFloat = 1.0

    var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0
    if self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) {
        return UIColor(red: 1.0 - red, green: 1.0 - green, blue: 1.0 - blue, alpha: alpha)
    }

    var hue: CGFloat = 0.0, saturation: CGFloat = 0.0, brightness: CGFloat = 0.0
    if self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) {
        return UIColor(hue: 1.0 - hue, saturation: 1.0 - saturation, brightness: 1.0 - brightness, alpha: alpha)
    }

    var white: CGFloat = 0.0
    if self.getWhite(&white, alpha: &alpha) {
        return UIColor(white: 1.0 - white, alpha: alpha)
    }

    return self
}

Objective-C

- (UIColor *)inverseColor {
    CGFloat alpha;

    CGFloat red, green, blue;
    if ([self getRed:&red green:&green blue:&blue alpha:&alpha]) {
        return [UIColor colorWithRed:1.0 - red green:1.0 - green blue:1.0 - blue alpha:alpha];
    }

    CGFloat hue, saturation, brightness;
    if ([self getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]) {
        return [UIColor colorWithHue:1.0 - hue saturation:1.0 - saturation brightness:1.0 - brightness alpha:alpha];
    }

    CGFloat white;
    if ([self getWhite:&white alpha:&alpha]) {
        return [UIColor colorWithWhite:1.0 - white alpha:alpha];
    }

    return nil;
}

---- DEPRECATED ----

Based on @grc's answer, I create a UIColor category with this method:

- (UIColor *)inverseColor {

    CGColorRef oldCGColor = self.CGColor;

    int numberOfComponents = CGColorGetNumberOfComponents(oldCGColor);

    // can not invert - the only component is the alpha
    // e.g. self == [UIColor groupTableViewBackgroundColor]
    if (numberOfComponents == 1) {
        return [UIColor colorWithCGColor:oldCGColor];
    }

    const CGFloat *oldComponentColors = CGColorGetComponents(oldCGColor);
    CGFloat newComponentColors[numberOfComponents];

    int i = numberOfComponents - 1;
    newComponentColors[i] = oldComponentColors[i]; // alpha
    while (--i >= 0) {
        newComponentColors[i] = 1 - oldComponentColors[i];
    }

    CGColorRef newCGColor = CGColorCreate(CGColorGetColorSpace(oldCGColor), newComponentColors);
    UIColor *newColor = [UIColor colorWithCGColor:newCGColor];
    CGColorRelease(newCGColor);

    return newColor;
}