最近在開(kāi)發(fā)中遇到一個(gè)自定義色值的需求眷蜈,界面如下:
效果圖
原理就是:HSV與RGB的轉(zhuǎn)化過(guò)程
概述部分
1. HSV(六角錐形體模型):
H - 色調(diào)
S - 飽和度
V - 明度
電視驶忌、顯示器顯示的顏色模式。
2. 確定HSV后惕耕,效果圖功能:
· 色相(下半部分)- hue
色相
色相組成:過(guò)渡色值幸海,選擇確定hue,純色值坡脐。
(255泄私,0, 0)- > (255, 0, 255) - > (0, 0, 255) - > (0, 255, 255) - > (0, 255, 0) - > (255, 255, 0) - > (255, 0, 0)
· 色板(上半部分)- sat备闲、val
看成坐標(biāo)系的話晌端,
S = 1, V = 1原色,純色
S = 0, V = x顏色最淺恬砂,被描述為灰色(即為黑白兩色)咧纠,H無(wú)意義。
V = 0, S = x顏色都是黑色泻骤,無(wú)亮度漆羔,H、S均無(wú)意義狱掂。
色板
代碼部分
1. 下邊這段代碼是:已知RGB換算出HSV演痒,進(jìn)而在效果圖中確定選中點(diǎn)。
此處說(shuō)明下符欠,剛開(kāi)始使用了系統(tǒng)API嫡霞,得到的hsv值有問(wèn)題,所以使用了自定義獲取方法希柿,使用后OK诊沪。
//系統(tǒng)
- (BOOL)getHue:(nullable CGFloat *)hue saturation:(nullable CGFloat *)saturation brightness:(nullable CGFloat *)brightness alpha:(nullable CGFloat *)alpha API_AVAILABLE(ios(5.0));
// 自定義: rgb -> hsv
- (MyHSV)getHSVWithRGB:(MyColor)color{
MyHSV hsv;
CGFloat var_R = (color.r/255.0); //RGB from 0 to 255
CGFloat var_G = (color.g/255.0);
CGFloat var_B = (color.b/255.0);
CGFloat var_Min = MIN(var_R, MIN(var_G, var_B)); //Min. value of RGB
CGFloat var_Max = MAX(var_R, MAX(var_G, var_B)); //Max. value of RGB
CGFloat del_Max = var_Max - var_Min; //Delta RGB value
hsv.v = var_Max;
if ( del_Max == 0 ){ //This is a gray, no chroma...{
hsv.h = 0; //HSV results from 0 to 1
hsv.s = 0;
}else{ //Chromatic data...
hsv.s = del_Max / var_Max;
CGFloat del_R = ( ( ( var_Max - var_R ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max;
CGFloat del_G = ( ( ( var_Max - var_G ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max;
CGFloat del_B = ( ( ( var_Max - var_B ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max;
if( var_R == var_Max ){
hsv.h = del_B - del_G;
}else if ( var_G == var_Max ){
hsv.h = ( 1 / 3.0 ) + del_R - del_B;
}else if (var_B == var_Max) {
hsv.h = ( 2 / 3.0 ) + del_G - del_R;
}
if ( hsv.h < 0 ) {
hsv.h += 1;
}else if (hsv.h > 1){
hsv.h -= 1;
}
}
return hsv;
}
2. 下邊兩段代碼是根據(jù)色相、色板(hsv)確定RGB
色相(顏色條)手勢(shì)
- (void)touchBarWithPoint:(CGPoint)point flag:(short)flag{
//改變指示器位置
CGRect frame = self.barPoint.frame;
frame.origin.x = point.x - 7;
self.barPoint.frame = frame;
//顏色計(jì)算器部分
int r,g,b;
int n = 1530 * [self check: point.x / self.colorBar.frame.size.width];
//初始化顏色顯示(1曾撤,0端姚, 0)- > (1, 0, 1) - > (0, 0, 1) - > (0, 1, 1) - > (0, 1, 0) - > (1, 1, 0) - > (1, 0, 0)
switch (n/255) {
case 0: r = 255; g = 0; b = n; break;
case 1: r = 255 - (n % 255); g = 0; b = 255; break;
case 2: r = 0; g = n % 255; b = 255; break;
case 3: r = 0; g = 255; b = 255 - (n % 255); break;
case 4: r = n % 255; g = 255; b = 0; break;
case 5: r = 255; g = 255 - (n % 255); b = 0; break;
default: r = 255; g = 0; b = 0; break;
}
self.colora = [self setMyColorWithR:r G:g B:b A:1];
self.brightImageView.backgroundColor = [self transformMyColorToUIColor:self.colora];
[self touchBrightWithPoint:CGPointMake(0, 0) flag:-1];
}
色板手勢(shì)
- (void)touchBrightWithPoint:(CGPoint)point flag:(short)flag{
if(flag == -1)
{
point = self.brightPoint.frame.origin;
point.x += 7;
point.y += 7;
}
//改變指示器位置
CGRect frame = self.brightPoint.frame;
frame.origin.x = point.x - 7;
frame.origin.y = point.y - 7;
self.brightPoint.frame = frame;
int r,g,b;
double xrate = [self check: point.x / self.brightImageView.frame.size.width];
double yrate = 1 - [self check: point.y / self.brightImageView.frame.size.height];
// sv圖 - 左側(cè)焦點(diǎn)
MyColor tempa = [self setMyColorWithR:255 * yrate G:255 * yrate B:255 * yrate A:1];
r = self.colora.r * yrate;
g = self.colora.g * yrate;
b = self.colora.b * yrate;
// sv圖 - 右側(cè)焦點(diǎn)
MyColor tempb = [self setMyColorWithR:r G:g B:b A:1];
r = tempb.r + (1 - xrate) * (tempa.r - tempb.r);
g = tempb.g + (1 - xrate) * (tempa.g - tempb.g);
b = tempb.b + (1 - xrate) * (tempa.b - tempb.b);
MyColor tempColor = [self setMyColorWithR:r G:g B:b A:1];
NSString *xColor = [NSString stringWithFormat:@"#%02x%02x%02x", tempColor.r, tempColor.g, tempColor.b];
if ([xColor isKindOfClass:[NSString class]]) {
[self.valueLabel showColor:xColor.uppercaseString];
if (_tempBlock) {
if (_selAlpha < 1) {
_tempBlock([CommUtls getRGBAcolorWithHexString:xColor colorAlpha:_selAlpha]);
}else{
_tempBlock(xColor);
}
}
}
}