I've googled for ages and can't find a way to do this. Anybody got an idea? There is an NSColor way of doing it for mac, but nothing for iPhone that开发者_StackOverflow中文版 I can see. The idea in my app is that the user types in a HEX code (which i have managed to get into RGB) and it's changed into HSB.
Ideas?
It just takes a little bit of math. The following code is just the important parts of the custom class I created for conversion. The "HSBColor" class stores just the hue, saturation, and brightness and I provide functions to get the components of it or a UIColor if I need to actually use it for something in the system.
Note: This code will not work as is unless you define an HSBColor class with hue, brightness, and saturation properties.
+(void)max:(int*)max andMin:(int*)min ofArray:(float[])array
{
*min=0;
*max=0;
for(int i=1; i<3; i++)
{
if(array[i] > array[*max])
*max=i;
if(array[i] < array[*min])
*min=i;
}
}
+(HSBColor*)colorWithRed:(float)red Green:(float)green Blue:(float)blue
{
HSBColor* toReturn = [[[HSBColor alloc] init] autorelease];
float colorArray[3];
colorArray[0] = red;
colorArray[1] = green;
colorArray[2] = blue;
//NSLog(@"RGB: %f %f %f",colorArray[0],colorArray[1],colorArray[2]);
int max;
int min;
[self max:&max andMin:&min ofArray:colorArray];
if(max==min)
{
toReturn.hue=0;
toReturn.saturation=0;
toReturn.brightness=colorArray[0];
}
else
{
toReturn.brightness=colorArray[max];
toReturn.saturation=(colorArray[max]-colorArray[min])/(colorArray[max]);
if(max==0) // Red
toReturn.hue = (colorArray[1]-colorArray[2])/(colorArray[max]-colorArray[min])*60/360;
else if(max==1) // Green
toReturn.hue = (2.0 + (colorArray[2]-colorArray[0])/(colorArray[max]-colorArray[min]))*60/360;
else // Blue
toReturn.hue = (4.0 + (colorArray[0]-colorArray[1])/(colorArray[max]-colorArray[min]))*60/360;
}
return toReturn;
}
+(HSBColor*)colorWithSystemColor:(UIColor*)color
{
const CGFloat* components = CGColorGetComponents(color.CGColor);
return [self colorWithRed:components[0] Green:components[1] Blue:components[2]];
}
In case you need it:
Convert HSV to RGB (From GLPaint sample application AppController.m)
//FUNCTIONS:
/*
HSL2RGB Converts hue, saturation, luminance values to the equivalent red, green and blue values.
For details on this conversion, see Fundamentals of Interactive Computer Graphics by Foley and van Dam (1982, Addison and Wesley)
You can also find HSL to RGB conversion algorithms by searching the Internet.
See also http://en.wikipedia.org/wiki/HSV_color_space for a theoretical explanation
*/
static void HSL2RGB(float h, float s, float l, float* outR, float* outG, float* outB)
{
float temp1,
temp2;
float temp[3];
int i;
// Check for saturation. If there isn't any just return the luminance value for each, which results in gray.
if(s == 0.0) {
if(outR)
*outR = l;
if(outG)
*outG = l;
if(outB)
*outB = l;
return;
}
// Test for luminance and compute temporary values based on luminance and saturation
if(l < 0.5)
temp2 = l * (1.0 + s);
else
temp2 = l + s - l * s;
temp1 = 2.0 * l - temp2;
// Compute intermediate values based on hue
temp[0] = h + 1.0 / 3.0;
temp[1] = h;
temp[2] = h - 1.0 / 3.0;
for(i = 0; i < 3; ++i) {
// Adjust the range
if(temp[i] < 0.0)
temp[i] += 1.0;
if(temp[i] > 1.0)
temp[i] -= 1.0;
if(6.0 * temp[i] < 1.0)
temp[i] = temp1 + (temp2 - temp1) * 6.0 * temp[i];
else {
if(2.0 * temp[i] < 1.0)
temp[i] = temp2;
else {
if(3.0 * temp[i] < 2.0)
temp[i] = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp[i]) * 6.0;
else
temp[i] = temp1;
}
}
}
// Assign temporary values to R, G, B
if(outR)
*outR = temp[0];
if(outG)
*outG = temp[1];
if(outB)
*outB = temp[2];
}
精彩评论