[原创]ActionScript3游戏中的图像编程(连载十八)

总目录:http://www.cnblogs.com/iloveas/p/3879125.html

 

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):Object
106         {
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 = 0
118             }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 }
原文地址:https://www.cnblogs.com/iloveas/p/3888563.html