首页 > 代码库 > ActionScript3游戏中的图像编程(连载十八)
ActionScript3游戏中的图像编程(连载十八)
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 ) } } }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。