How do I determine darker or lighter color variant of a given color?

前端 未结 13 635
情话喂你
情话喂你 2020-12-04 07:37

Given a source color of any hue by the system or user, I\'d like a simple algorithm I can use to work out a lighter or darker variants of the selected color. Similar to effe

13条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-04 08:06

    HSV ( Hue / Saturation / Value ) also called HSL ( Hue / Saturation / Lightness ) is just a different color representation.

    Using this representation is it easier to adjust the brightness. So convert from RGB to HSV, brighten the 'V', then convert back to RGB.

    Below is some C code to convert

    void RGBToHSV(unsigned char cr, unsigned char cg, unsigned char cb,double *ph,double *ps,double *pv)
    {
    double r,g,b;
    double max, min, delta;
    
    /* convert RGB to [0,1] */
    
    r = (double)cr/255.0f;
    g = (double)cg/255.0f;
    b = (double)cb/255.0f;
    
    max = MAXx(r,(MAXx(g,b)));
    min = MINx(r,(MINx(g,b)));
    
    pv[0] = max;
    
    /* Calculate saturation */
    
    if (max != 0.0)
        ps[0] = (max-min)/max;
    else
        ps[0] = 0.0; 
    
    if (ps[0] == 0.0)
    {
        ph[0] = 0.0f;   //UNDEFINED;
        return;
    }
    /* chromatic case: Saturation is not 0, so determine hue */
    delta = max-min;
    
    if (r==max)
    {
        ph[0] = (g-b)/delta;
    }
    else if (g==max)
    {
        ph[0] = 2.0 + (b-r)/delta;
    }
    else if (b==max)
    {
        ph[0] = 4.0 + (r-g)/delta;
    }
    ph[0] = ph[0] * 60.0;
    if (ph[0] < 0.0)
        ph[0] += 360.0;
    }
    
    void HSVToRGB(double h,double s,double v,unsigned char *pr,unsigned char *pg,unsigned char *pb)
    {
    int i;
    double f, p, q, t;
    double r,g,b;
    
    if( s == 0 )
    {
        // achromatic (grey)
        r = g = b = v;
    }
    else
    {
        h /= 60;            // sector 0 to 5
        i = (int)floor( h );
        f = h - i;          // factorial part of h
        p = v * ( 1 - s );
        q = v * ( 1 - s * f );
        t = v * ( 1 - s * ( 1 - f ) );
        switch( i )
        {
        case 0:
            r = v;
            g = t;
            b = p;
        break;
        case 1:
            r = q;
            g = v;
            b = p;
        break;
        case 2:
            r = p;
            g = v;
            b = t;
        break;
        case 3:
            r = p;
            g = q;
            b = v;
        break;
        case 4:
            r = t;
            g = p;
            b = v;
        break;
        default:        // case 5:
            r = v;
            g = p;
            b = q;
        break;
        }
    }
    r*=255;
    g*=255;
    b*=255;
    
    pr[0]=(unsigned char)r;
    pg[0]=(unsigned char)g;
    pb[0]=(unsigned char)b;
    }
    

提交回复
热议问题