移动开发俱乐部

自定义色值RGB转HSV

2021-03-18  本文已影响0人  恩莱客

最近在开发中遇到一个自定义色值的需求,界面如下:

效果图
原理就是:HSV与RGB的转化过程

概述部分

1. HSV(六角锥形体模型):

H - 色调
S - 饱和度
V - 明度
电视、显示器显示的颜色模式。

2. 确定HSV后,效果图功能:
· 色相(下半部分)- hue
色相
色相组成:过渡色值,选择确定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均无意义。


色板

代码部分

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);
           }
       }
   }
}
上一篇 下一篇

猜你喜欢

热点阅读