总目录:http://blog.csdn.net/iloveas2014/article/details/38304477
1.3.4 HSB与RGB互转公式的ActionScript实现
为了让HSB转RGB这个通用的功能在后续的项目里可以重用,我们先把这个转换公式做成一个工具类,并且放入到公共类库里。当然,这样的类,网上也有很多现成的可以直接拿过来用(个人推荐frocessing工具包)。类里的算法看起来跟公式会有点出入,一方面我自己也是从网上东拼西凑弄回来的,另一方面我把S和L/B的取值范围从0~1改成了0~100。
package com.gemei.geom {
public class ConvertColor{
/**
* 将RGB转为HSB
* @param r int 红色通道值
* @param g int 绿色通道值
* @param b int 蓝色通道值
* @return 一个包含h,s和b三个属性的对象(色相0~360,饱和度0~100,亮度0~100)
**/
public static function RGBToHSB(r:int,g:int,b:int):Object{
var hsb:Object = new Object();
//HSB模式需要经常用到RGB中的最大,最小值,故先拿个变量存起来
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;
//h比较麻烦,要分情况,但是写起来也不算复杂
if(hsb.s == 0){
hsb.h = 0;
}else{
switch(max){
case r:
hsb.h = ((g - b)/(max - min)*60 + 360) % 360;
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;
}
/**
* 将HSB转为RGB(色相0~360,饱和度0~100,亮度0~100)
* @param h int 色相值
* @param s int 饱和度值
* @param b int 亮度值
* @return 一个包含r,g和b三个属性的对象
**/
public static function HSBToRGB(h:int,s:int,b:int):Object{
var rgb:Object = new Object();
//按RGB转HSB的公式,拿到最大和最小值
var max:Number = (b*0.01)*255;
var min:Number = max*(1-(s*0.01));
//然后根据色相的运算方法,确定max和min值花落谁家
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;
}
public static function RGBToHSL(r:int,g:int,b:int):Object
{
var innerR:Number = r / 255;
var innerG:Number = g / 255;
var innerB:Number = b / 255;
var hsl:Object = new Object();
var min:Number = Math.min(innerR, innerG, innerB);
var max:Number = Math.max(innerR, innerG, innerB);
var delta:Number = max - min;
hsl.l = (max + min) / 2;
if(delta == 0){
hsl.h = 0;
hsl.s = 0
}else{
if (hsl.l < 0.5 ){
hsl.s = delta / (max + min);
}else{
hsl.s = delta / ( 2 - max - min);
}
if(hsl.s == 0){
hsl.h = 0;
}else{
switch(max){
case innerR:
hsl.h = ((innerG - innerB)/(max - min) * 60 + 360) % 360;
break;
case innerG:
hsl.h = (innerB - innerR)/(max - min) * 60 + 120;
break;
case innerB:
hsl.h = (innerR - innerG)/(max - min) * 60 + 240;
break;
}
}
}
hsl.l *= 100;
hsl.s *= 100;
return hsl;
}
/**
* 将HSL转为RGB(h=0~360,s=0~100,l=0~100)
*
**/
public static function HSLToRGB(h:int, s:int, l:int):Object{
var rgb:Object = new Object();
var innerH:Number = h / 360;
var innerS:Number = s / 100;
var innerL:Number = l /100;
if ( s == 0 ){
rgb.r = innerL * 255;
rgb.g = innerL * 255;
rgb.b = innerL * 255;
}else{
var var2:Number;
if ( innerL < 0.5 ){
var2 = innerL * ( 1 + innerS );
}else{
var2 = ( innerL + innerS ) - ( innerS * innerL );
}
var var1:Number = 2 * innerL - var2;
rgb.r = 255 * HueToRGB( var1, var2, innerH + ( 1 / 3 ) ) ;
rgb.g = 255 * HueToRGB( var1, var2, innerH );
rgb.b = 255 * HueToRGB( var1, var2, innerH - ( 1 / 3 ) );
}
return rgb;
}
private static function HueToRGB( v1:Number, v2:Number, vH:Number):Number{
if ( vH < 0 ) vH += 1;
if ( vH > 1 ) vH -= 1;
if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH );
if ( ( 2 * vH ) < 1 ) return ( v2 );
if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 );
return ( v1 )
}
}
}