'How to convert UIColor to Hexadecimal (web color text string)?
Is there an easy way to convert UIColor to a hexadecimal value ?
Or do we have to get the RGB components with CGColorGetComponents and then work it out from there?
e.g CGColorGetComponents(color.CGColor)[0] * 256 ?
Solution 1:[1]
I would consider using Erica Sadun's UIColor category. It includes a lot of functionality for free, including hex representations. It's pretty easy to use, just add it to whatever class header you're using it in or, add it to the pre-compiled header for ultimate flexibility. If you're adding to the pre-compiled header, do so similar to something like this:
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "UIColor-Expanded.h"
#endif
Then You can use it like so NSLog(@"%@", [myColor hexStringFromColor]);
GitHub link to the UIColor category: https://github.com/erica/uicolor-utilities
ArsTechnica article about it: http://arstechnica.com/apple/guides/2009/02/iphone-development-accessing-uicolor-components.ars
Solution 2:[2]
I also had to convert a UIColor to its hex components.
As already pointed out by lewiguez there is a very good category at github that does all that stuff.
But because I wanted to learn how it is done I made my own simple implementation for RGB colours.
+ (NSString*)colorToWeb:(UIColor*)color
{
NSString *webColor = nil;
// This method only works for RGB colors
if (color &&
CGColorGetNumberOfComponents(color.CGColor) == 4)
{
// Get the red, green and blue components
const CGFloat *components = CGColorGetComponents(color.CGColor);
// These components range from 0.0 till 1.0 and need to be converted to 0 till 255
CGFloat red, green, blue;
red = roundf(components[0] * 255.0);
green = roundf(components[1] * 255.0);
blue = roundf(components[2] * 255.0);
// Convert with %02x (use 02 to always get two chars)
webColor = [[NSString alloc]initWithFormat:@"%02x%02x%02x", (int)red, (int)green, (int)blue];
}
return webColor;
}
All feedback is welcome!
Solution 3:[3]
Other than the widely used string based solution, here's a hex (integer) based solution. Usage:
UIColor* color = lf_rgb(0x120aef);
log(@"color %.6x", color.hex_rgb);
And you'll get "color 120aef". I'll put these code in https://github.com/superarts/LCategory, or you can copy-paste into your own code bank too:
#define lf_rgb(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
@interface UIColor (lc_rgb)
- (NSInteger)hex_rgb;
@end
@implementation UIColor (lc_rgb)
- (NSInteger)hex_rgb
{
CGFloat r, g, b, a;
BOOL result = [self getRed:&r green:&g blue:&b alpha:&a];
// log(@"rgba: %f, %f, %f, %f", r * 255, g * 255, b * 255, a * 255);
if ((result == NO) || (a != 1.0f))
return -1;
return
(NSInteger)(r * 255) * 256 * 256 +
(NSInteger)(g * 255) * 256 +
(NSInteger)(b * 255) * 1;
}
@end
Solution 4:[4]
There isn't, as far as I know, any built in solution.
Note however, that you should multiply by 255 instead of 256.
Getting an hexadecimal representation is an easy task, so you won't have many troubles to build the string manually.
NSLog(@"%X%X%X", redInteger, greenInteger, blueInteger);
Solution 5:[5]
This is how I do did it with Swift 3:
extension UIColor {
var hex:String{
get{
var red:CGFloat = 0
var blue:CGFloat = 0
var green:CGFloat = 0
var alpha:CGFloat = 0
self.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
let rgb:Int = (Int)(red*255)<<16 | (Int)(green*255)<<8 | (Int)(blue*255)<<0
return String.localizedStringWithFormat("#%06x", rgb)
}
}
}
Or you can make it a method. I just like how color.hex looks vs color.hex().
Solution 6:[6]
Here's a Swift 5 solution, as extensions to UIColor, to convert UIColor object to a hex color string of RGB (#RRGGBB) form or RGBA (#RRGGBBAA) format ,and also use either format and create a UIColor, with option to provide an alpha argument with #RRGGBB form as non-default value of 1.0 for alpha.
I started with @boidkan's answer then searched around for other solutions on S.O. and then refined and optimized them to a solution I could live with, and tested them in playground.
/* Returns UIColor as "#RRGGBB" (hex string) */
var hexRGB : String {
func comp(_ value: CGFloat, _ byteShift: Int = 0) -> Int { return Int(value * 0xff) << (byteShift * 8) }
var r = CGFloat(0), b = CGFloat(0), g = CGFloat(0), a = CGFloat(0)
getRed(&r, green: &g, blue: &b, alpha: &a)
return String(format: "#%6.6X", comp(r, 2) | comp(g, 1) | comp(b))
}
/* Returns UIColor as "#RRGGBBAA" (hex string) */
var hexRGBA : String {
func comp(_ value: CGFloat, _ byteShift: Int = 0) -> Int { return Int(value * 0xff) << (byteShift * 8) }
var r = CGFloat(0), b = CGFloat(0), g = CGFloat(0), a = CGFloat(0)
getRed(&r, green: &g, blue: &b, alpha: &a)
return String(format: "#%8.8X", comp(r, 3) | comp(g, 2) | comp(b, 1) | comp(a))
}
/*
* Returns UIColor object given input of the one of the following formats, where:
*
* RR = Red component as hex value 00-FF
* GG = Green component as hex value 00-FF
* BB = Blue component as hex value 00-FF
* AA = Alpha componenet as hex value 00-FF
* a = Alpha component as 0.00 - 1.00 (a is optional, defaults to 1.0)
*
* ("RRGGBB"[, a]), ("#RRGGBB"[, a]), ("RRGGBBAA"), or ("#RRGGBBA")
*/
convenience init(hexRGBA: String, alpha: CGFloat = 1.0) {
let cleanHex = hexRGBA.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
.replacingOccurrences(of: #"[^0-9a-fA-F]"#, with: "", options: .regularExpression)
assert(cleanHex.count == 6 || cleanHex.count == 8, "Bad RGB/RGBA value")
var rgbIntValue: UInt64 = 0
Scanner(string:cleanHex).scanHexInt64(&rgbIntValue)
let hh1 = CGFloat( Double((rgbIntValue & 0xff000000) >> 24) / 255.0)
let hh2 = CGFloat( Double((rgbIntValue & 0x00ff0000) >> 16) / 255.0)
let hh3 = CGFloat( Double((rgbIntValue & 0x0000ff00) >> 8) / 255.0)
let hh4 = CGFloat( Double((rgbIntValue & 0x000000ff) / 255.0)
if (cleanHex.count == 8) {
self.init(red: hh1, green: hh2, blue: hh3, alpha: hh4)
return
}
self.init(red: hh2, green: hh3, blue: hh4, alpha: alpha) /* RGB + A */
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | lewiguez |
| Solution 2 | Luc Wollants |
| Solution 3 | superarts.org |
| Solution 4 | |
| Solution 5 | |
| Solution 6 |
