开发者

Programmatically darken a Hex colour [closed]

开发者 https://www.devze.com 2022-12-12 02:34 出处:网络
Closed. This question is opinion-based. It is not currently accepting answers. Want to improve this question? Update the question so it can be answered with facts and citations by editing
Closed. This question is opinion-based. It is not currently accepting answers.

Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.

开发者_开发知识库

Closed 5 years ago.

Improve this question

What's the easiest way to programmatically darken a hex colour?


If you're not bothered about too much control, and just want a generally darker version of a colour, then:

col = (col & 0xfefefe) >> 1;

Is a nice quick way to halve a colour value (assuming it's packed as a byte per channel, obviously).

In the same way brighter would be:

col = (col & 0x7f7f7f) << 1;


Convert hex color into integer RBG components:

#FF6600 = rbg(255, 102, 0)

If you want to make it darker by 5%, then simply reduce all integer values by 5%:

255 - 5% = 242
102 - 5% = 96
0 - 5% = 0

= rbg(242, 96, 0)

Convert back to hex color

= #F26000


A function implemented in javascript:

// credits: richard maloney 2006
function getTintedColor(color, v) {
    if (color.length >6) { color= color.substring(1,color.length)}
    var rgb = parseInt(color, 16); 
    var r = Math.abs(((rgb >> 16) & 0xFF)+v); if (r>255) r=r-(r-255);
    var g = Math.abs(((rgb >> 8) & 0xFF)+v); if (g>255) g=g-(g-255);
    var b = Math.abs((rgb & 0xFF)+v); if (b>255) b=b-(b-255);
    r = Number(r < 0 || isNaN(r)) ? 0 : ((r > 255) ? 255 : r).toString(16); 
    if (r.length == 1) r = '0' + r;
    g = Number(g < 0 || isNaN(g)) ? 0 : ((g > 255) ? 255 : g).toString(16); 
    if (g.length == 1) g = '0' + g;
    b = Number(b < 0 || isNaN(b)) ? 0 : ((b > 255) ? 255 : b).toString(16); 
    if (b.length == 1) b = '0' + b;
    return "#" + r + g + b;
} 

Example:

> getTintedColor("ABCEDEF", 10)
> #c6f7f9


Well, I don't have any pseudocode for you, but a tip. If you want to darken a color and maintain its hue, you should convert that hex to HSB (hue, saturation, brightness) rather than RGB. This way, you can adjust the brightness and it will still look like the same color without hue shifting. You can then convert that HSB back to hex.


given arg darken_factor # a number from 0 to 1, 0=no change, 1=black
for each byte in rgb_value
    byte = byte * (1 - darken_factor)


I pieced together a nice two-liner function for this:

Programmatically Lighten or Darken a hex color (or rgb, and blend colors)

shadeColor2(hexcolor,-0.05) for 5% darker

shadeColor2(hexcolor,-0.25) for 25% darker

Use positives for lightening.


  • Split the hex color into its RGB components.
  • Convert each of these components into an integer value.
  • Multiply that integer by a fraction, such as 0.5, making sure the result is also integer.
    • Alternatively, subtract a set amount from that integer, being sure not to go below 0.
  • Convert the result back to hex.
  • Concatenate these values in RGB order, and use.


RGB colors (in hexadecimal RGB notation) get darker or lighter by adjusting shade, key, lightness, or brightness. See the playground: colorizer.org


Option 1. Translate R, G, B values to darken shade

This one is simple, but easy to mess up. Here is subtracting 16 points off the (0,255) scale from each value:

myHex = 0x8c36a9;
darkerHex = myHex - 0x101010;
#  0x7c2699;

The hex will underflow if any of the R,G,B values are 0x0f or lower. Something like this would fix that.

myHex = 0x87f609;
darkenBy = 0x10;
floor = 0x0;

darkerHex = (max((myHex >> 16) - darkenBy, floor) << 16) + \
    (max(((myHex & 0xff00) >> 8) - darkenBy, floor) << 8) + \
    max(((myHex & 0xff) - darkenBy), floor);
# 0x77e600

# substitute `ceiling=0xff;` and `min((myHex ...) + lightenBy, ceiling)` for lightening

Option 2. Scale R, G, B values to increase black

In the CMYK model, key (black) is 1 - max of R, G, B values on (0,1) scale.

This one is simple enough that you can get good results without too much code. You're rescaling the distribution of R, G, B values by a single scaling factor.

Express the scaling factor as 2-digit hex (so 50% would be .5*0x100 or 0x80, 1/16th is 0x10 and 10% rounds down to 0x19 ).

#  Assumes integer division ... looking at you python3 >:(

myHex = 0x8c36a9;
keyFactor = 0x10;                   #  Lighten or darken by 6.25%
R = myHex >> 16;                    #  0x8c
G = (myHex & 0xff00) >> 8;          #  0x36
B = myHex & 0xff;                   #  0xa9

darkerHex = ((R-R*keyFactor/0x100) << 16) +  # Darker R
            ((G-G*keyFactor/0x100) << 8) +   # Darker G
            (B-B*keyFactor/0x100);           # Darker B
#  0x84339f

#  substitute `(X+keyFactor-X*keyFactor/0x100)` for lightening 
#  0x9443af

Option 3. Reduce Lightness or Brightness at constant hue

In the HSL representation of RGB, lightness is the midpoint between min and max of R, G, B values. For HSV, brightness is the max of R, G, B values.

Consider using your language's built-in or external RGB/HEX to HSL/HSV converter. Then adjust your L/V values and convert back to RGB/HSL. You can do the conversion by hand, as in #1 & #2, but the implementation may not save you any time over an existing converter (see links for the maths).


You should consider darken the color in L*a*b* color space. Here's an example in JavaScript using chroma.js:

chroma.hex("#FCFC00").darker(10).hex()  // "#dde000"


A hex colour such as #FCFCFC consists of three pairs representing RGB. The second part of each pair can be reduced to darken any colour without altering the colour considerably.

eg. to darken #FCFCFC, lower the values of C to give #F0F0F0

Reducing the first part of each pair by a small amount will also darken the colour, but you will start to affect the colour more (eg. turning a green to a blue).

0

精彩评论

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