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).