How To Calculate The Average Between 2 Colors In ActionScript 3.0

mb-plastic-calculator-color In some web apps or flash games, we probably need to calculate the average between 2 colors, for example. feed 0xAA0000 and 0xCC0000, and return 0xBB0000 ? Is there a simple way to calculate between two hex colors?

AverageColor is a open source(Licensed under the MIT License) util-class to calculate the average between 2 colors (Hex, RGB or HSB format).

There are only 2 classes in AverageColor library. Calculate the average color with AverageColor.as, and convert RGB/HSB/16 color with ConvertColor.as class. They were released by scratchbrain(Japanese).You can download AverageColor library here.

AverageColor.as

Function averageHex: average 2 hex colors.
Function averageRgb: average 2 RGB colors.
Function averageHsb: average 2 HSBcolors.

package net.scratchbrain.color
{
	import net.scratchbrain.color.AverageColor;
	public class AverageColor
	{

		public static function averageHex(_hex1:uint,_hex2:uint):uint
		{
			var rgb1:Object = ConvertColor.HexToRGB(_hex1);
			var rgb2:Object = ConvertColor.HexToRGB(_hex2);
			var hsb1:Object = ConvertColor.RGBToHSB(rgb1.r,rgb1.g,rgb1.b);
			var hsb2:Object = ConvertColor.RGBToHSB(rgb2.r,rgb2.g,rgb2.b);
			return averageHsb(hsb1.h,hsb1.s,hsb1.b,hsb2.h,hsb2.s,hsb2.b);

		}
		public static function averageRgb(_r1:int,_g1:int,_b1:int,_r2:int,_g2:int,_b2:int):uint
		{
			var hsb1:Object = ConvertColor.RGBToHSB(_r1,_g1,_b1);
			var hsb2:Object = ConvertColor.RGBToHSB(_r2,_g2,_b2);
			return averageHsb(hsb1.h,hsb1.s,hsb1.b,hsb2.h,hsb2.s,hsb2.b);
		}
		public static function averageHsb(_h1:int,_s1:int,_b1:int,_h2:int,_s2:int,_b2:int):uint
		{
			var _h:int;
			var _s:int;
			var _b:int;

			if(_h1 <= 18 && _s1 != 0 && _h2 >= 180){
				_h1 = 360;
			}
			if(_h2 <= 18 && _s2 != 0 && _h1 >= 180){
				_h2 = 360;
			}

			if(_s1 != 0 && _s2 != 0){
				_h = (_h1 + _h2)/2;
				_s = (_s1 + _s2)/2;
				_b = (_b1 + _b2)/2;
			}else if(_s1 == 0 && _s2 == 0				_h = 0;
				_s = 0;
				_b = (_b1 + _b2)/2;
			}else
				_h = (_h1 != 0) ? _h1 : _h2;
				_s = (_s1 + _s2)/2;
				_b = (_b1 + _b2)/2;
			}

			var rgb:Object = ConvertColor.HSBToRGB(_h,_s,_b);
			return ConvertColor.RGBToHex(rgb.r,rgb.g,rgb.b);
		}
	}
}

ConvertColor.as

Function RGBToHex: convert from RGB to Hex
Function HexToRGB: convert from HEX to RGB
Function RGBToHSB: convert RGB to HSB
Function HSBToRGB: convert HSB to RGB

package net.scratchbrain.color
{
	public class ConvertColor
	{
		// convert from RGB to Hex
		public static function RGBToHex(r:int,g:int,b:int):uint
		{
			var hex:uint = r<<16 | g<<8 | b;
			return hex;
		}
		// convert from HEX to RGB
		public static function HexToRGB(value:uint):Object{
			var rgb:Object = new Object();
			rgb.r = (value >> 16) & 0xFF
			rgb.g = (value >> 8 ) & 0xFF
			rgb.b = value & 0xFF
			return rgb;
		}
		// convert RGB to HSB
		public static function RGBToHSB(r:int,g:int,b:int):Object{
			var hsb:Object = new Object;
			var _max:Number = Math.max(r,g,b);
			var _min:Number = Math.min(r,g,b);

			hsb.s = (_max != 0) ? (_max - _min) / _max * 100: 0;
			hsb.b = _max / 255 * 100;
			if(hsb.s == 0){
				hsb.h = 0;
			}else{
				switch(_max)
				{
					case r:
						hsb.h = (g - b)/(_max - _min)*60 + 0;
						break;
					case g:
						hsb.h = (b - r)/(_max - _min)*60 + 120;
						break;
					case b:
						hsb.h = (r - g)/(_max - _min)*60 + 240;
						break;
				}
			}

			hsb.h = Math.min(360, Math.max(0, Math.round(hsb.h)))
			hsb.s = Math.min(100, Math.max(0, Math.round(hsb.s)))
			hsb.b = Math.min(100, Math.max(0, Math.round(hsb.b)))

			return hsb;
		}
		// convert HSB to RGB
		public static function HSBToRGB(h:int,s:int,b:int):Object{
			var rgb:Object = new Object();

			var max:Number = (b*0.01)*255;
			var min:Number = max*(1-(s*0.01));

			if(h == 360){
				h = 0;
			}

			if(s == 0){
				rgb.r = rgb.g = rgb.b = b*(255*0.01) ;
			}else{
				var _h:Number = Math.floor(h / 60);

				switch(_h){
					case 0:
						rgb.r = max	;
						rgb.g = min+h * (max-min)/ 60;
						rgb.b = min;
						break;
					case 1:
						rgb.r = max-(h-60) * (max-min)/60;
						rgb.g = max;
						rgb.b = min;
						break;
					case 2:
						rgb.r = min ;
						rgb.g = max;
						rgb.b = min+(h-120) * (max-min)/60;
						break;
					case 3:
						rgb.r = min;
						rgb.g = max-(h-180) * (max-min)/60;
						rgb.b =max;
						break;
					case 4:
						rgb.r = min+(h-240) * (max-min)/60;
						rgb.g = min;
						rgb.b = max;
						break;
					case 5:
						rgb.r = max;
						rgb.g = min;
						rgb.b = max-(h-300) * (max-min)/60;
						break;
					case 6:
						rgb.r = max;
						rgb.g = min+h  * (max-min)/ 60;
						rgb.b = min;
						break;
				}

				rgb.r = Math.min(255, Math.max(0, Math.round(rgb.r)))
				rgb.g = Math.min(255, Math.max(0, Math.round(rgb.g)))
				rgb.b = Math.min(255, Math.max(0, Math.round(rgb.b)))
			}
			return rgb;
		}
	}
}

Useage

1. import

import net.scratchbrain.color.AverageColor;

2. call function

Calculate the average between 2 HEX colors:

var _color:uint = AverageColor.averageHex(_color1.selectedColor,_color2.selectedColor);

Calculate the average between 2 RGB colors:

var _color:uint = AverageColor.averageRgb(_r1.value,_g1.value,_b1.value,_r2.value,_g2.value,_b2.value);

Calculate the average between 2 HSB colors:

var _color:uint = AverageColor.averageHsb(_h1.value,_s1.value,_v1.value,_h2.value,_s2.value,_v2.value);

Author URL

http://www.scratchbrain.net/blog/ver2/entries/000445.html (Japanese)

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • Reddit
  • Technorati
  • StumbleUpon
  • Twitter
RSS Enjoy this Post? Subscribe to Ntt.cc

RSS Feed   RSS Feed     Email Feed  Email Feed Follow us Follow us
You can leave a response, or trackback from your own site.

5 Responses to “How To Calculate The Average Between 2 Colors In ActionScript 3.0”

  1. Nathan says:

    Wouldn’t it be easier to convert to a number and find the average directly.

    I mean
    Number((Number(0xAA0000) + Number(0xCC0000)) / 2).toString(16) = bb0000

    • Mr. LieR says:

      I think that’s OK
      but not friendly to read source code.
      probably also maintain

    • senocular says:

      The direct average of numbers case doesn’t always work. Consider averaging:
      0×000100 and 0×000000

      Finding the numeric average gives you 0×000080 – which is a lot of blue when you started off without any on either side. The actual color average is half a point of green, 00 or 01, depending on how you round it. And this is what you would get after separating the value into its individual color components, though round tripping through HSB is an unnecessary step.

  2. Mr. LieR says:

    the same with:
    we can write all source in one function
    but in fact we will not.
    right?

  3. [...] can help you to make the candle flame fluttered effect in the breeze. Similar the previous library: How To Calculate The Average Between 2 Colors In ActionScript 3.0, there is only one as3 source file in TeraFire library. You can easily to modify and to adapt to [...]

Leave a Reply