[原创]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 }