【问题标题】:How can I calculate shades of a given hex color in actionscript 3?如何在 actionscript 3 中计算给定十六进制颜色的阴影?
【发布时间】:2011-01-16 13:24:48
【问题描述】:

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

【问题讨论】:

    标签: flash actionscript-3 actionscript colors


    【解决方案1】:

    这是我为最近的一个项目编写的一个函数,它允许您根据 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);
    }
    

    【讨论】:

      【解决方案2】:

      最准确的方法是将 RGB 值转换为 HSL 或 HSV(色相、饱和度、亮度/亮度),然后调整饱和度和/或亮度/亮度值(不考虑色相)。然后转换回RGB。

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

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

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

      因此,当您说较轻时,您可能更倾向于白色,但也可能意味着更倾向于灰色(去饱和)。或者可能两者兼而有之。

      将 RGB 值转换为色相、饱和度和亮度后,您只需将亮度乘以 > 1 的某个数字使其更亮,或将饱和度乘以某个小于 1 的值使其更灰。然后转换回RGB。

      我不知道动作脚本,但这里是 RGB->HSB 和 HSB->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;
      

      【讨论】:

        【解决方案3】:

        这是从我的颜色工具中提取的一些内容。听起来 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;
            }
        

        【讨论】:

          【解决方案4】:

          我已将 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));
              }
          

          【讨论】:

            【解决方案5】:

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

            【讨论】:

            • 抱歉 - 我刚刚意识到您的意思是纯 Flash,而不是 Flex。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-04-03
            • 2011-04-20
            • 1970-01-01
            • 1970-01-01
            • 2011-10-25
            • 2012-05-01
            • 2012-06-28
            相关资源
            最近更新 更多