16

Lets say I have a UIColor

UIColor *color = [UIColor redColor];

Now I want to modify the saturation/hue/brigthness, how do I do that? I did read the documentation but i'm still really confused

I want to modify the UIColor I made ([UIColor redColor]) not initiate a new color with some preferences. How do I modify it retaining the original. I do know about thecolorWithHue:saturation:brightness:alpha: method, I need to update an existing color's properties, keeping the red color.

s6luwJ0A3I
  • 1,023
  • 1
  • 9
  • 22

10 Answers10

23

You can call getHue:saturation:brightness:alpha: on your color, then adjust the values, then create a new color with your adjusted components using +[UIColor colorWithHue:saturation:brightness:alpha:]

CGFloat hue, saturation, brightness, alpha ;
BOOL ok = [ <color> getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha ] ;
if ( !ok ) { 
    // handle error 
}
// ... adjust components..

UIColor * newColor = [ UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha ] ;
ryohey
  • 115
  • 1
  • 8
nielsbot
  • 15,922
  • 4
  • 48
  • 73
  • Thanks a lot for your answer, it worked! I'l just accept it in a min (Stackoverflow says i have to wait) – s6luwJ0A3I Mar 15 '13 at 09:21
  • 4
    This works, however it doesn't meet your requirement that it be the same color object. But what you want isn't possible. UIColor is immutable--so you will always have to create a new color object. – nielsbot Mar 15 '13 at 09:38
  • @nielsbot I like your concise use of BOOL to kill 2 birds with one stone, so to speak. Excellent answer... – Charles Robertson Dec 02 '16 at 22:18
17

Here is swift UIColor extension you might find useful:

extension UIColor {

    func modified(withAdditionalHue hue: CGFloat, additionalSaturation: CGFloat, additionalBrightness: CGFloat) -> UIColor {

        var currentHue: CGFloat = 0.0
        var currentSaturation: CGFloat = 0.0
        var currentBrigthness: CGFloat = 0.0
        var currentAlpha: CGFloat = 0.0

        if self.getHue(&currentHue, saturation: &currentSaturation, brightness: &currentBrigthness, alpha: &currentAlpha){
            return UIColor(hue: currentHue + hue,
                           saturation: currentSaturation + additionalSaturation,
                           brightness: currentBrigthness + additionalBrightness,
                           alpha: currentAlpha)
        } else {
            return self
        }
    }
}
ambientlight
  • 7,212
  • 3
  • 49
  • 61
3

Unfortunately it's quite a hassle to change any of the hsba or rgba values of a UIColor by default. Using HandyUIKit (install it via Carthage) makes your life a lot easier:

import HandyUIKit  

// each line creates a new UIColor object with the new value
color.change(.hue,        to: 0.1)
color.change(.brightness, to: 0.2)
color.change(.saturation, to: 0.3)
color.change(.alpha,      to: 0.4)

// chaining them returns a single new object with all values changed
color.change(.hue,        to: 0.5)
     .change(.brightness, to: 0.6)
     .change(.saturation, to: 0.7)

There are also options to apply relative changes:

// create a new UIColor object with hue & brightness increased by 0.2
color.change(.hue,        by: 0.2)
     .change(.brightness, by: 0.2)

The library also adds some other handy UI features into your project – checkout its README on GitHub for more details.

I hope it helps!

Jeehut
  • 20,202
  • 8
  • 59
  • 80
3

One important note not yet mentioned here is that your UIColor should be in extended RGB space. Depending on how your color is originally created this function may return false if it's just RGB.

Secondly, I made a variant on @ambientlight's answer to make the API just a little more slick. You can adjust 1 or all properties.

extension UIColor {

    public func adjust(hueBy hue: CGFloat = 0, saturationBy saturation: CGFloat = 0, brightnessBy brightness: CGFloat = 0) -> UIColor {

        var currentHue: CGFloat = 0.0
        var currentSaturation: CGFloat = 0.0
        var currentBrigthness: CGFloat = 0.0
        var currentAlpha: CGFloat = 0.0

        if getHue(&currentHue, saturation: &currentSaturation, brightness: &currentBrigthness, alpha: &currentAlpha) {
            return UIColor(hue: currentHue + hue,
                       saturation: currentSaturation + saturation,
                       brightness: currentBrigthness + brightness,
                       alpha: currentAlpha)
        } else {
            return self
        }
    }
}
bitwit
  • 2,589
  • 2
  • 28
  • 33
0

You can use this method by setting the following values

UIColor *customColor = [UIColor colorWithHue: x.xx saturation: x.xx brightness: x.xx alpha: 1.0];

Rajan Balana
  • 3,775
  • 25
  • 42
0

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIColor_Class/Reference/Reference.html

There is a class function with colorWithHue:saturation:brightness:alpha:

Of course you can first use getHue:saturation:brightness:alpha: before making any changes when you init with [UIColor redColor]

Black Maggie
  • 496
  • 2
  • 15
-1

You can simply modify this by

[UIColor colorWithHue:YourHueValue saturation:YourSaturationValue brightness:YourBrightnessValueValue alpha:1.00];

alpha denotes the opaqueness of view and it ranges from 0.0 - 1.0

Maulik
  • 19,348
  • 14
  • 82
  • 137
Akhil PK
  • 91
  • 5
-1

UIColor can't change the saturation/hue/brigthness,you can you CoreImage.

Some sample code below:

CIFilter *filter = [CIFilter filterWithName:@"CIColorControls"];

[filter setValue:[NSNumber numberWithFloat:1.0] forKey:@"inputContrast"];
[filter setValue:[NSNumber numberWithFloat:1.0] forKey:@"inputSaturation"];
[filter setValue:[NSNumber numberWithFloat:0.0] forKey:@"inputBrightness"];


[filter setValue:_A_CIImage_ forKey:kCIInputImageKey];

CIImage *_outputImage = filter.outputImage;

CIContext context = [CIContext contextWithOptions:nil];

CGImageRef outputImageRef = [context createCGImage: _outputImage fromRect:[_outputImage extent]];
elixenide
  • 44,308
  • 16
  • 74
  • 100
  • colorWithHue:saturation:brightness:alpha: Creates and returns a color object using the specified opacity and HSB color space component values. This method used for make a color with HSB color space , like RGB color space. Can't change a red color to other color. – zhoujinhao Mar 15 '13 at 09:27
-1
CGSize imageSize = [ba size];
CGRect imageExtent = CGRectMake(0,0,imageSize.width,imageSize.height);

// Create a context containing the image.
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();

[sourceimage drawInRect:imageExtent];
// Draw the hue on top of the image.
CGContextSetBlendMode(context, kCGBlendModeHue);
[[UIColor colorWithHue:yourvalue saturation:1.0 brightness:1 alpha:1.0] set];
UIBezierPath *imagePath = [UIBezierPath bezierPathWithRect:imageExtent];
[imagePath fill];

CGImageRef imageref=CGBitmapContextCreateImage(context);

UIImage *result =[UIImage imageWithCGImage:imageref];

CGImageRelease(imageref);

In the first two lines it describes image size and image rect. CGContextRef is used to create a context in core graphics. After that the 5th line is the image you want to apply hue and rect of image. After that blend mode which is important. After that UI colorWithHue in which values of hue, saturation, brightness and alpha are passed. To get a proper effect give 1.0 value of alpha. And at the end you should set uicolor.create bezerpath or you can directly give cgcontextsetfill(context). At the end create imageref and put that image in UIImage. At the end, as always in choreographics, release CGImageRelease to hedge from memory issues.

ZygD
  • 22,092
  • 39
  • 79
  • 102
  • Provided code might help, but in order to make it a good answer you should also describe/explain why/how exactly does your code solve the problem. – ZygD Jun 15 '15 at 11:06
  • in first two line it describe image size and image rect. cgcontext is use to create a context in core graphics.after that 5th line is image uyou want to apply hue and rect of image . after that blend mode which is important.after that ui colorWithHue in which pass value of hue ,saturation,brightness and alpha to get proper effect give 1.0 value of alpha.and at end set uicolor.create bezerpath or u can directly give cgcontextsetfill(context). At the end create imageref and put that image in uiimage .AT the end alway in choreographics release cgimageRef against memory issue. – Arvind Rajpurohit Jun 15 '15 at 11:16
  • It's always better to put relevant info inside the answer, as not everyone, if they have a similar problem, will dig into comments. Also, what did you mean by [choreographics](http://www.thefreedictionary.com/choreographic)? – ZygD Jun 15 '15 at 11:31
-4
[UIColor colorWithHue:0.10 saturation:0.16 brightness:0.13 alpha:1.00];
Rahul
  • 134
  • 6
  • A simple line(s) of code is not considered a good answer. Please also explain why you did what and how this is helping. – Lukas Knuth Mar 15 '13 at 11:40