自定义色值RGB转HSV
2021-03-18 本文已影响0人
恩莱客
最近在开发中遇到一个自定义色值的需求,界面如下:
![](https://img.haomeiwen.com/i2640927/85c52387178b114a.png)
原理就是:HSV与RGB的转化过程
概述部分
1. HSV(六角锥形体模型):
H - 色调
S - 饱和度
V - 明度
电视、显示器显示的颜色模式。
2. 确定HSV后,效果图功能:
· 色相(下半部分)- hue
![](https://img.haomeiwen.com/i2640927/556ccefed03b5fc9.png)
色相组成:过渡色值,选择确定hue,纯色值。
(255,0, 0)- > (255, 0, 255) - > (0, 0, 255) - > (0, 255, 255) - > (0, 255, 0) - > (255, 255, 0) - > (255, 0, 0)
· 色板(上半部分)- sat、val
看成坐标系的话,
S = 1, V = 1原色,纯色
S = 0, V = x颜色最浅,被描述为灰色(即为黑白两色),H无意义。
V = 0, S = x颜色都是黑色,无亮度,H、S均无意义。
![](https://img.haomeiwen.com/i2640927/88eedd128385b7bf.png)
代码部分
1. 下边这段代码是:已知RGB换算出HSV,进而在效果图中确定选中点。
此处说明下,刚开始使用了系统API,得到的hsv值有问题,所以使用了自定义获取方法,使用后OK。
//系统
- (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. 下边两段代码是根据色相、色板(hsv)确定RGB
色相(颜色条)手势
- (void)touchBarWithPoint:(CGPoint)point flag:(short)flag{
//改变指示器位置
CGRect frame = self.barPoint.frame;
frame.origin.x = point.x - 7;
self.barPoint.frame = frame;
//颜色计算器部分
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];
}
色板手势
- (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图 - 左侧焦点
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图 - 右侧焦点
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);
}
}
}
}