How can I calculate shades of a given hex color in actionscript 3?

后端 未结 5 636
天命终不由人
天命终不由人 2020-12-31 22:39

I need a way to calculate lighter hex color(s) based on a provided one. I realize I could use a color transform, but I need the actual value in order to generate a gradient.

5条回答
  •  执笔经年
    2020-12-31 23:45

    The most accurate way to do this is to convert the RGB value to HSL or HSV (Hue, Saturation, Luminance/Brightness) and then adjust the saturation and or luminance/brightness values (leaving the hue alone). Then convert back to RGB.

    When you try to do math on RGB values directly, you tend to get hue changes.

    Saturation is how pure the color is, a value of 0.0 is grey, while a value of 1.0 is pure color.

    Luminance/Brightness aren't the same thing, but they are similar. They both are used to move a value towards black or white.

    So when you say lighter, you probably mean more towards white, but you may also mean more towards grey (desaturated). Or possibly both.

    Once you have your RGB value converted into Hue, Saturation and Brightness, then you just multiply brightness by some number > 1 to make it brighter, or Saturation by some value < 1 to make it greyer. then convert back to RGB.

    I don't know action script, but here is C style pseudocode for RGB->HSB and HSB->RGB.

    RGB to HSB

    unsigned int RGB;
    double   red   = ((RGB >> 16) & 0xFF) / 255.0; // red value between 0.0 and 1.0
    double   green = ((RGB >> 8) & 0xFF) / 255.0;
    double   blue  = ((RGB) & 0xFF) / 255.0);
    
    double   dmax = max(max(red, green) blue);
    double   dmin = min(min(red, green) blue);
    double   range = dmax - dmin;
    
    double   brite = dmax;
    double   sat   = 0.0;
    double   hue   = 0.0;  // hue is always 0 when sat is 0
    
    if (dmax != 0.0)  sat = range / dmax;
    
    if (sat != 0.0) 
    {
       if (red == dmax)
          hue = (green - blue) / range;
       else if (green = dmax)
          hue = 2.0 + (blue - red) / range;
       else if (blue == dmax)
          hue = 4.0 + (green - red) / range;
    
       // it is conventional to convert hue to a value between 0 and 360.0 (a color circle)
       hue = hue * 60;
       if (hue < 0.0)
          hue = hue + 360.0;
    }
    
    // result is now in hue, sat, & brite variables
    

    HSB to RGB

    double hue, sat, brite; // these are inputs
    
    double red, green, blue;
    
    if (sat == 0.0)
    {
       red   = brite;
       green = brite;        
       blue  = brite;
    }       
    else
    {
       if (hue == 360.0)
          hue = 0;
    
       int slice = (int)(hue / 60.0);
       double hue_frac = (hue / 60.0) - slice;
    
       double aa = brite * (1.0 - sat);
       double bb = brite * (1.0 - sat * hue_frac);
       double cc = brite * (1.0 - sat * (1.0 - hue_frac));
    
       switch (slice)
       {
           case 0: red = brite; green = cc;     blue = aa;    break;
           case 1: red = bb;    green = brite;  blue = aa;    break;
           case 2: red = aa;    green = brite;  blue = cc;    break;
           case 3: red = aa;    green = bb;     blue = brite; break;
           case 4: red = cc;    green = aa;     blue = brite; break;
           case 5: red = brite; green = aa;     blue = bb;    break;
          default: red = 0.0;   green = 0.0;    blue = 0.0;   break;
       }
    
    }
    
    int ir = (int)(red * 255);
    int ig = (int)(green * 255);
    int ib = (int)(blue * 255);
    
    // this is the result.
    unsigned int RGB = (ir << 16) | (ig << 8) | ib;
    

提交回复
热议问题