Skip to content

Instantly share code, notes, and snippets.

@hmcfletch
Created January 23, 2012 05:59
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save hmcfletch/1661029 to your computer and use it in GitHub Desktop.
Save hmcfletch/1661029 to your computer and use it in GitHub Desktop.
A bunch of objective-c color helpers
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
// generate a UIColor from rgb and alpha values
#define RGBA(r, g, b, a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a]
#define RGB(r, g, b) RGBA(r, g, b, 1.0)
// generate a UIColor
#define GRAYSCALEA(rgb, a) RGBA(rgb, rgb, rgb, a)
#define GRAYSCALE(rgb) GRAYSCALEA(rgb, 1.0)
// generate a UIColor from a hex and an alpha value
#define HEXCOLORA(rgbValue, a) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16)) / 255.0 green:((float)((rgbValue & 0xFF00) >> 8)) / 255.0 blue:((float)(rgbValue & 0xFF)) / 255.0 alpha:a]
#define HEXCOLOR(rgbValue) HEXCOLORA(rgbValue, 1.0)
@interface ColorHelper : NSObject
// UImage of a solid color and size. Good for placeholders.
+ (UIImage *)imageFromColor:(UIColor *)color andSize:(CGSize)size;
// vertical linear gradient at the given frame from topColor to bottomColor
+ (CAGradientLayer *)gradientWithFrame:(CGRect)frame fromColor:(UIColor *)topColor toColor:(UIColor *)bottomColor;
// darkens a UIColor by a given amount
+ (UIColor *)darkenColor:(UIColor *)oldColor percentOfOriginal:(float)amount;
// lightens a UIColor by a given amount
+ (UIColor *)lightenColor:(UIColor *)oldColor byPercentage:(float)amount;
@end
@implementation ColorHelper
+ (UIImage *)imageFromColor:(UIColor *)color andSize:(CGSize)size
{
CGRect rect = CGRectMake(0, 0, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
+ (CAGradientLayer *)gradientWithFrame:(CGRect)frame fromColor:(UIColor *)topColor toColor:(UIColor *)bottomColor
{
CAGradientLayer *shadowGradient = [CAGradientLayer layer];
shadowGradient.frame = frame;
shadowGradient.colors = [NSArray arrayWithObjects:(id)[topColor CGColor], (id)[bottomColor CGColor], nil];
return shadowGradient;
}
+ (UIColor *)darkenColor:(UIColor *)oldColor percentOfOriginal:(float)amount
{
float percentage = amount / 100.0;
int totalComponents = CGColorGetNumberOfComponents(oldColor.CGColor);
bool isGreyscale = totalComponents == 2 ? YES : NO;
CGFloat* oldComponents = (CGFloat *)CGColorGetComponents(oldColor.CGColor);
CGFloat newComponents[4];
if (isGreyscale) {
newComponents[0] = oldComponents[0]*percentage;
newComponents[1] = oldComponents[0]*percentage;
newComponents[2] = oldComponents[0]*percentage;
newComponents[3] = oldComponents[1];
} else {
newComponents[0] = oldComponents[0]*percentage;
newComponents[1] = oldComponents[1]*percentage;
newComponents[2] = oldComponents[2]*percentage;
newComponents[3] = oldComponents[3];
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef newColor = CGColorCreate(colorSpace, newComponents);
CGColorSpaceRelease(colorSpace);
UIColor *retColor = [UIColor colorWithCGColor:newColor];
CGColorRelease(newColor);
return retColor;
}
+ (UIColor *)lightenColor:(UIColor *)oldColor byPercentage:(float)amount
{
float percentage = amount / 100.0;
int totalComponents = CGColorGetNumberOfComponents(oldColor.CGColor);
bool isGreyscale = totalComponents == 2 ? YES : NO;
CGFloat* oldComponents = (CGFloat *)CGColorGetComponents(oldColor.CGColor);
CGFloat newComponents[4];
// FIXME: Clean this SHITE up
if (isGreyscale) {
newComponents[0] = oldComponents[0]*percentage + oldComponents[0] > 1.0 ? 1.0 : oldComponents[0]*percentage + oldComponents[0];
newComponents[1] = oldComponents[0]*percentage + oldComponents[0] > 1.0 ? 1.0 : oldComponents[0]*percentage + oldComponents[0];
newComponents[2] = oldComponents[0]*percentage + oldComponents[0] > 1.0 ? 1.0 : oldComponents[0]*percentage + oldComponents[0];
newComponents[3] = oldComponents[0]*percentage + oldComponents[1] > 1.0 ? 1.0 : oldComponents[1]*percentage + oldComponents[1];
} else {
newComponents[0] = oldComponents[0]*percentage + oldComponents[0] > 1.0 ? 1.0 : oldComponents[0]*percentage + oldComponents[0];
newComponents[1] = oldComponents[1]*percentage + oldComponents[1] > 1.0 ? 1.0 : oldComponents[0]*percentage + oldComponents[1];
newComponents[2] = oldComponents[2]*percentage + oldComponents[2] > 1.0 ? 1.0 : oldComponents[0]*percentage + oldComponents[2];
newComponents[3] = oldComponents[3]*percentage + oldComponents[3] > 1.0 ? 1.0 : oldComponents[0]*percentage + oldComponents[3];
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef newColor = CGColorCreate(colorSpace, newComponents);
CGColorSpaceRelease(colorSpace);
UIColor *retColor = [UIColor colorWithCGColor:newColor];
CGColorRelease(newColor);
return retColor;
}
@end
@bartjacobs
Copy link

In lightenColor:byPercentage:, it isn't necessary to alter the alpha value of the color. Also, wouldn't it be easier to make these methods instance methods (instead of class methods) by placing them in an Objective-C category on UIColor?

You can clean up lightenColor:byPercentage: a bit more by using the MIN function.

if (isGreyscale) {
    newComponents[0] = MIN(oldComponents[0] * value, 1.0);
    newComponents[1] = MIN(oldComponents[0] * value, 1.0);
    newComponents[2] = MIN(oldComponents[0] * value, 1.0);
    newComponents[3] = oldComponents[1];
} else {
    newComponents[0] = MIN(oldComponents[0] * value, 1.0);
    newComponents[1] = MIN(oldComponents[1] * value, 1.0);
    newComponents[2] = MIN(oldComponents[2] * value, 1.0);
    newComponents[3] = oldComponents[3];
}

I hope this helps.

@rchampourlier
Copy link

Thanks for sharing, thanks @bartjacobs for the great comment.

I would add this to this bunch of helpers:

+ (UIColor *)colorWithHexColorString:(NSString*)hexColorString
{
  UIColor* result = nil;
  unsigned colorCode = 0;
  unsigned char redByte, greenByte, blueByte;

  if (nil != hexColorString)
  {
    NSScanner* scanner = [NSScanner scannerWithString:hexColorString];
    (void) [scanner scanHexInt:&colorCode]; // ignore error
  }
  redByte = (unsigned char)(colorCode >> 16);
  greenByte = (unsigned char)(colorCode >> 8);
  blueByte = (unsigned char)(colorCode); // masks off high bits

  result = [UIColor colorWithRed:(CGFloat)redByte / 0xff
                           green:(CGFloat)greenByte / 0xff
                            blue:(CGFloat)blueByte / 0xff
                           alpha:1.0];
  return result;
}

I took it from a StackOverflow question I think, but I haven't the source anymore. For the author, just comment and post the link ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment