开发者

How do I change hexidecimal colours programmatically to get lighter or darker?

开发者 https://www.devze.com 2023-01-06 18:21 出处:网络
I 开发者_开发技巧want to have a base colour, say 0x0066FF and I want every iteration after that to get slightly darker for example.Except your input color is some shade of gray, RGB is not going to cu

I 开发者_开发技巧want to have a base colour, say 0x0066FF and I want every iteration after that to get slightly darker for example.


Except your input color is some shade of gray, RGB is not going to cut it. RGB is useful for storing pixel data, but awful to manipulate in a "visualy" meaningful way.

I wrote a similar answer on a flash coders' list some time ago about this subject, so what follows is more or less a verbatim copy & paste of that answer. I hope you find it useful.

An accurate way to change the shade of a base color is transfoming the RGB value to the HSL color space, then adjust luminance (brightness), and transform back to RGB. Here's a handy class for transforming RGB <--> HLS.

http://www.dreaminginflash.com/2007/11/19/hls-to-rgb-rgb-to-hls/

Here's some test code:

import ColorUtils;
var rgb:Number = 0x336699;
var hls:Object = ColorUtils.RGBtoHLS(rgb);
var darkL:Number  = Math.max(hls.l - 0.2,0);
var lightL:Number  = Math.min(hls.l + 0.2,1);
var dark:Number = ColorUtils.HLStoRGB(hls.h,darkL,hls.s);
var light:Number = ColorUtils.HLStoRGB(hls.h,lightL,hls.s);
var origBmd:BitmapData   = new BitmapData(40,40,false,rgb);
var darkerBmd:BitmapData = new BitmapData(40,40,false,dark);
var lighterBmd:BitmapData = new BitmapData(40,40,false,light);
var origBm:Bitmap = new Bitmap(origBmd);
var darkerBm:Bitmap = new Bitmap(darkerBmd);
var lighterBm:Bitmap = new Bitmap(lighterBmd);

darkerBm.y  = 0;
origBm.y  = 50;
lighterBm.y = 100;

addChild(origBm);
addChild(darkerBm);
addChild(lighterBm);


0x000000 is black, so anything closer to black is darker (or more gray, anyways). So if you split the difference in each byte between itself and 0x00, it's a quick darkening.

0x00 / 2 = 0x00
0x66 / 2 = 0x33
0xff / 2 = 0x80

--> 0x0033ff

You can split it in 10 and iterate removing 1/10ths if you want 10 shades, for example.

Update:

I wrote this a while ago:

    /**
     * Create new color blended into another.
     * @param color to blend
     * @param into other color
     * @param factor amount of original color to keep, i.e. 0 would be no "color", all "into"
     * @param blendAlpha uses the 0xFF000000 part of the color as well
             * @returns blended color uint
     */
    public static function blendColor( color:uint, into:uint=0xFFFFFFFF, factor:Number=0.5, blendAlpha:Boolean=false ) : uint
    {
        if( factor < 0 || factor > 1 ) factor = 0.5;
        var a1:uint = ( color >> 24 ) & 0xFF;
        var r1:uint = ( color >> 16 ) & 0xFF;
        var g1:uint = ( color >>  8 ) & 0xFF;
        var b1:uint = ( color >>  0 ) & 0xFF;
        var a2:uint = (  into >> 24 ) & 0xFF;
        var r2:uint = (  into >> 16 ) & 0xFF;
        var g2:uint = (  into >>  8 ) & 0xFF;
        var b2:uint = (  into >>  0 ) & 0xFF;
        var a3:uint = ( a1*factor + a2*(1-factor) ) & 0xFF;
        var r3:uint = ( r1*factor + r2*(1-factor) ) & 0xFF;
        var g3:uint = ( g1*factor + g2*(1-factor) ) & 0xFF;
        var b3:uint = ( b1*factor + b2*(1-factor) ) & 0xFF;
        return ( blendAlpha?a3<<24:0x0 ) | (r3<<16) | (g3<<8) | b3;
    }


0x00 00 00 is RED GREEN BLUE. Meaning 0xFF0000 is pure red, 0x00FF00 is pure green, 0x0000FF is pure blue. So if you want to get darker, lower the hex values starting from 0xFF. If you're looking to scale the darkness from 0x0066FF you will want to ensure you maintain the same ratio of RGB. Meaning 0xFF00FF -> 0xCC00CC -> 0x990099 -> 0x660066 -> 0x330033 -> 0x000000.

Forgive the partial answer, but hopefully this is enough for you to figure out more specific implementation details on your own.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号