如何计算动作3中给定十六进制颜色的阴影?

时间:2010-02-13 19:51:37

标签: flash actionscript-3 actionscript colors

我需要一种基于提供的颜色计算较轻的十六进制颜色的方法。我意识到我可以使用颜色转换,但我需要实际值才能生成渐变。

5 个答案:

答案 0 :(得分:7)

这是我为最近的项目编写的一个函数,它允许您根据0-1的范围在两个其他项目之间找到颜色值。我认为它将满足您的需求

private function getBetweenColourByPercent(value:Number = 0.5 /* 0-1 */, highColor:uint = 0xFFFFFF, lowColor:uint = 0x000000):uint {
    var r:uint = highColor >> 16;
    var g:uint = highColor >> 8 & 0xFF;
    var b:uint = highColor & 0xFF;

    r += ((lowColor >> 16) - r) * value;
    g += ((lowColor >> 8 & 0xFF) - g) * value;
    b += ((lowColor & 0xFF) - b) * value;

    return (r << 16 | g << 8 | b);
}

答案 1 :(得分:6)

最准确的方法是将RGB值转换为HSL或HSV(色调,饱和度,亮度/亮度),然后调整饱和度和/或亮度/亮度值(仅保留色调)。然后转换回RGB。

当您尝试直接对RGB值进行数学运算时,您往往会获得色调变化。

饱和度是颜色的纯度,0.0的值是灰色,而值1.0是纯色。

亮度/亮度不是一回事,但它们是相似的。它们都用于将值移向黑色或白色。

因此,当你说更轻时,你可能更倾向于白色,但你也可能更倾向于灰色(去饱和)。或者两者都可能。

将RGB值转换为色相,饱和度和亮度后,您只需将亮度乘以某个数字&gt; 1使其更亮,或饱和度为某个值&lt; 1让它变灰。然后转换回RGB。

我不知道动作脚本,但这里是RGB-&gt; HSB和HSB-&gt; RGB的C风格伪代码。

RGB到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到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;

答案 2 :(得分:5)

这里有一些东西从我的Color utils中拉出来。听起来像makeGradient可能对你有用。

    /**
     * Return a gradient given a color.
     *
     * @param color      Base color of the gradient.
     * @param intensity  Amount to shift secondary color.
     * @return An array with a length of two colors.
     */
    public static function makeGradient(color:uint, intensity:int = 20):Array
    {
        var c:Object = hexToRGB(color);
        for (var key:String in c)
        {
            c[key] += intensity;
            c[key] = Math.min(c[key], 255); // -- make sure below 255
            c[key] = Math.max(c[key], 0);   // -- make sure above 0
        }
        return [color, RGBToHex(c)];
    }

    /**
     * Convert a uint (0x000000) to a color object.
     *
     * @param hex  Color.
     * @return Converted object {r:, g:, b:}
     */
    public static function hexToRGB(hex:uint):Object
    {
        var c:Object = {};

        c.a = hex >> 24 & 0xFF;
        c.r = hex >> 16 & 0xFF;
        c.g = hex >> 8 & 0xFF;
        c.b = hex & 0xFF;

        return c;
    }

    /**
     * Convert a color object to uint octal (0x000000).
     *
     * @param c  Color object {r:, g:, b:}.
     * @return Converted color uint (0x000000).
     */
    public static function RGBToHex(c:Object):uint
    {
        var ct:ColorTransform = new ColorTransform(0, 0, 0, 0, c.r, c.g, c.b, 100);
        return ct.color as uint
    }

另外,不记得我从哪里得到这个,但这些静态函数会生成一个颜色的和声列表:

    /**
     * Convert RGB bits to a hexcode
     *
     * @param r  Red bits
     * @param g  Green bits
     * @param b  Blue bits
     * @return A color as a uint
     */
    public static function convertToHex(r:uint, g:uint, b:uint):uint
    {
        var colorHexString:uint = (r << 16) | (g << 8) | b;
        return colorHexString;
    }

    /**
     * Get a series of complements of a given color.
     *
     * @param color   Color to get harmonies for
     * @param weight  Threshold to apply to color harmonies, 0 - 255
     */
    public static function getHarmonies(color:uint, weight:Number):Array
    {
        var red:uint = color >> 16;
        var green:uint = (color ^ (red << 16)) >> 8;
        var blue:uint = (color ^ (red << 16)) ^ (green << 8);

        var colorHarmonyArray:Array = new Array();
        //weight = red+green+blue/3;

        colorHarmonyArray.push(convertToHex(red, green, weight));
        colorHarmonyArray.push(convertToHex(red, weight, blue));
        colorHarmonyArray.push(convertToHex(weight, green, blue));
        colorHarmonyArray.push(convertToHex(red, weight, weight));
        colorHarmonyArray.push(convertToHex(weight, green, weight));
        colorHarmonyArray.push(convertToHex(weight, weight, blue));

        return colorHarmonyArray;
    }

答案 3 :(得分:2)

我已将c代码翻译成AS3并修复了代码中的一些错误。 dmin正在计算rgb到hsb函数的最大值,以及计算蓝色时最大的色调应该是红色 - 绿色,否则青色和品红色会向后转。

RGB到HSB

    private function RGBtoHSB(_rgb:uint):Object {
        var red:Number = ((_rgb >> 16) & 0xFF) / 255.0;
        var green:Number = ((_rgb >> 8) & 0xFF) / 255.0;
        var blue:Number = ((_rgb) & 0xFF) / 255.0;

        var dmax:Number = Math.max(Math.max(red, green), blue);
        var dmin:Number = Math.min(Math.min(red, green), blue);
        var range:Number = dmax - dmin;

        var bright:Number = dmax;
        var sat:Number = 0.0;
        var hue:Number = 0.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 + (red - green) / range;
            }

            hue = hue * 60;
            if (hue < 0.0) {
                hue = hue + 360.0;
            }
        }

        return { "v":bright, "s":sat, "h":hue };
    }

HSB到RGB

    private function HSBtoRGB(_hue:Number, _sat:Number, _value:Number):uint {
        var red:Number = 0.0;
        var green:Number = 0.0;
        var blue:Number = 0.0;

        if (_sat == 0.0) {
            red = _value;
            green = _value;
            blue = _value;
        }else {
            if (_hue == 360.0) {
                _hue = 0;
            }

            var slice:int = _hue / 60.0;
            var hue_frac:Number = (_hue / 60.0) - slice;

            var aa:Number = _value * (1.0 - _sat);
            var bb:Number = _value * (1.0 - _sat * hue_frac);
            var cc:Number = _value * (1.0 - _sat * (1.0 - hue_frac));

            switch(slice) {
                case 0:
                    red = _value;
                    green = cc;
                    blue = aa;
                    break;
                case 1:
                    red = bb;
                    green = _value;
                    blue = aa;
                    break;
                case 2:
                    red = aa;
                    green = _value;
                    blue = cc;
                    break;
                case 3:
                    red = aa;
                    green = bb;
                    blue = _value;
                    break;
                case 4:
                    red = cc;
                    green = aa;
                    blue = _value;
                    break;
                case 5:
                    red = _value;
                    green = aa;
                    blue = bb;
                    break;
                default:
                    red = 0.0;
                    green = 0.0;
                    blue = 0.0;
                    break;
            }
        }

        var ired:Number = red * 255.0;
        var igreen:Number = green * 255.0;
        var iblue:Number = blue * 255.0;


        return ((ired << 16) | (igreen << 8) | (iblue));
    }

答案 4 :(得分:-1)

您是否看过mx.utils.ColorUtil和adjustBrightness方法?