首页 > 代码库 > ActionScript3游戏中的图像编程(连载十八)

ActionScript3游戏中的图像编程(连载十八)

1.3.4 HSB与RGB互转公式的ActionScript实现

        为了让HSB转RGB这个通用的功能在后续的项目里可以重用,我们先把这个转换公式做成一个工具类,并且放入到公共类库里。当然,这样的类,网上也有很多现成的可以直接拿过来用(个人推荐frocessing工具包)。类里的算法看起来跟公式会有点出入,一方面我自己也是从网上东拼西凑弄回来的,另一方面我把S和L/B的取值范围从0~1改成了0~100。

 

  1 package com.gemei.geom {   2     public class ConvertColor{   3         /**  4          * 将RGB转为HSB  5          * @param r int 红色通道值  6          * @param g int 绿色通道值  7          * @param b int 蓝色通道值  8          * @return 一个包含h,s和b三个属性的对象(色相0~360,饱和度0~100,亮度0~100)  9          **/ 10         public static function RGBToHSB(r:int,g:int,b:int):Object{  11             var hsb:Object = new Object();  12             //HSB模式需要经常用到RGB中的最大,最小值,故先拿个变量存起来 13             var max:Number = Math.max(r,g,b);  14             var min:Number = Math.min(r,g,b);  15             //饱和度和亮度的计算比较简单,按着公式来写即可 16             hsb.s = (max != 0) ? (max - min) / max * 100: 0;  17             hsb.b = max / 255 * 100;  18             //h比较麻烦,要分情况,但是写起来也不算复杂 19             if(hsb.s == 0){  20                 hsb.h = 0;  21             }else{  22                 switch(max){  23                     case r:  24                         hsb.h = ((g - b)/(max - min)*60 + 360) % 360;  25                         break;  26                     case g:  27                         hsb.h = (b - r)/(max - min)*60 + 120;  28                         break;  29                     case b:  30                         hsb.h = (r - g)/(max - min)*60 + 240;  31                         break;  32                 }  33             } 34             //这段代码拿来防止数值溢出的,实际上,只要计算的时候小心点,控制上下限的操作可有可无 35             hsb.h = Math.min(360, Math.max(0, Math.round(hsb.h)))  36             hsb.s = Math.min(100, Math.max(0, Math.round(hsb.s)))  37             hsb.b = Math.min(100, Math.max(0, Math.round(hsb.b)))   38             return hsb;  39         }  40         /** 41          * 将HSB转为RGB(色相0~360,饱和度0~100,亮度0~100) 42          * @param h int 色相值 43          * @param s int 饱和度值 44          * @param b int 亮度值 45          * @return 一个包含r,g和b三个属性的对象 46          **/ 47         public static function HSBToRGB(h:int,s:int,b:int):Object{  48             var rgb:Object = new Object(); 49             //按RGB转HSB的公式,拿到最大和最小值 50             var max:Number = (b*0.01)*255;  51             var min:Number = max*(1-(s*0.01));  52             //然后根据色相的运算方法,确定max和min值花落谁家 53             if(h == 360){  54                 h = 0;  55             } 56             if(s == 0){  57                 rgb.r = rgb.g = rgb.b = b*(255*0.01) ;  58             }else{  59                 var _h:Number = Math.floor(h / 60);                  60                 switch(_h){  61                     case 0:  62                         rgb.r = max; 63                         rgb.g = min+h * (max-min)/ 60;  64                         rgb.b = min;  65                         break;  66                     case 1:  67                         rgb.r = max-(h-60) * (max-min)/60;  68                         rgb.g = max;  69                         rgb.b = min;  70                         break;  71                     case 2:  72                         rgb.r = min ;  73                         rgb.g = max;  74                         rgb.b = min+(h-120) * (max-min)/60;  75                         break;  76                     case 3:  77                         rgb.r = min;  78                         rgb.g = max-(h-180) * (max-min)/60;  79                         rgb.b =max;  80                         break;  81                     case 4:  82                         rgb.r = min+(h-240) * (max-min)/60;  83                         rgb.g = min;  84                         rgb.b = max;  85                         break;  86                     case 5:  87                         rgb.r = max;  88                         rgb.g = min; 89                         rgb.b = max-(h-300) * (max-min)/60;  90                         break;  91                     case 6:  92                         rgb.r = max;  93                         rgb.g = min+h  * (max-min)/ 60;  94                         rgb.b = min;  95                         break;  96                 } 97                 //不多说了,也是防止数据溢出的代码 98                 rgb.r = Math.min(255, Math.max(0, Math.round(rgb.r)));  99                 rgb.g = Math.min(255, Math.max(0, Math.round(rgb.g))); 100                 rgb.b = Math.min(255, Math.max(0, Math.round(rgb.b))); 101             } 102             return rgb; 103         } 104         105         public static function RGBToHSL(r:int,g:int,b:int):Object106         {107             var innerR:Number = r / 255;108             var innerG:Number = g / 255;109             var innerB:Number = b / 255;110             var hsl:Object = new Object();111             var min:Number = Math.min(innerR, innerG, innerB);112             var max:Number = Math.max(innerR, innerG, innerB);113             var delta:Number = max - min;114             hsl.l = (max + min) / 2;115             if(delta == 0){116                 hsl.h = 0;117                 hsl.s = 0118             }else{119                 if (hsl.l < 0.5 ){120                     hsl.s = delta / (max + min);121                 }else{122                     hsl.s = delta / ( 2 - max - min);123                 }                124                 if(hsl.s == 0){ 125                     hsl.h = 0; 126                 }else{ 127                     switch(max){ 128                         case innerR: 129                             hsl.h = ((innerG - innerB)/(max - min) * 60 + 360) % 360; 130                             break;131                         case innerG: 132                             hsl.h = (innerB - innerR)/(max - min) * 60 + 120; 133                             break; 134                         case innerB: 135                             hsl.h = (innerR - innerG)/(max - min) * 60 + 240; 136                             break; 137                     } 138                 }139             }140             hsl.l *= 100;141             hsl.s *= 100;142             return hsl;143         }        144         145         /**146          * 将HSL转为RGB(h=0~360,s=0~100,l=0~100)147          * 148          **/149         public static function HSLToRGB(h:int, s:int, l:int):Object{150             var rgb:Object = new Object();151             var innerH:Number = h / 360;152             var innerS:Number = s / 100;153             var innerL:Number = l /100;    154             if ( s == 0 ){155                 rgb.r = innerL * 255; 156                 rgb.g = innerL * 255;157                 rgb.b = innerL * 255;158             }else{159                 var var2:Number;160                 if ( innerL < 0.5 ){161                     var2 = innerL * ( 1 + innerS );162                 }else{163                     var2 = ( innerL + innerS ) - ( innerS * innerL );164                 }165                 var var1:Number = 2 * innerL - var2;166                 rgb.r = 255 * HueToRGB( var1, var2, innerH + ( 1 / 3 ) ) ;167                 rgb.g = 255 * HueToRGB( var1, var2, innerH );168                 rgb.b = 255 * HueToRGB( var1, var2, innerH - ( 1 / 3 ) );    169             }170             return rgb;171         }172         173         private static function HueToRGB( v1:Number, v2:Number, vH:Number):Number{174             if ( vH < 0 ) vH += 1;175             if ( vH > 1 ) vH -= 1;176             if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH );177             if ( ( 2 * vH ) < 1 ) return ( v2 );178             if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 );179             return ( v1 )180         }    181     } 182 }