I'm creating a fast lookup table for colors. Let's say you give me shade of red, then I'll convert it to closest web safe color and perform the lookup. It will return many different shades of red and it's ok for my purposes.
The only problem I have right now is how do I convert a given RGB value to a web safe value? I'm using PIL and Python. I don't mind writing my own algorithm either but it's a bit too difficult for me.
I don't know if there is a specific way to do it with PIL, but if you have an rgb colour and we define the closest web safe colour as the one where the distance in the rgb space is the smallest, you can do it as follows:
def getwebsafe(r,g,b):
rw = 51 * ((int(r)+25)//51)
gw = 51 * ((int(g)+25)//51)
bw = 51 * ((int(b)+25)//51)
return (rw,gw,bw)
This is because web safe colors have 6 possible shades for each component: (0,51,102,153,204,255). If you a component in your colour is in the range [0,25] the closest is 0, if it's in the range [26-76] the closest is 51, etc.
Alternatively, a shorter version for an rgb colour represented as a list:
def getwebsafe(colour):
return [51*((int(c)+25)//51) for c in colour]
EDIT: Edited to make sure it works even when Python uses non-integer numbers for colours and for Python 2 and 3.
As I said in a comment under @pedrosorio's answer, I think this could be done more efficently by using table lookups. This means virtually all of the mathematical calculations are done once, when the table is created, and is only done 256 times, rather for each and every pixel. Here's what I mean, using pedrosorio's formula:
tbl = tuple(51*((int(i)+25)//51) for i in xrange(256))
def websafe(*color):
return tuple(tbl[c] for c in color)
safecolor = websafe(34,55,13)
However, I'm not sure about how the formula maps the 0-255 range values -- because it assigns the following number of entries for each of the six primary shades:
shade count
0x00 26
0x33 51
0x66 51
0x99 51
0xcc 51
0xff 26
Instead, I would use this slightly simpler formula:
tbl = tuple(51*(i//43) for i in xrange(256))
which gives a more even distribution of the shades:
shade count
0x00 43
0x33 43
0x66 43
0x99 43
0xcc 43
0xff 41
Once you know the distribution count you could even do something like this which involves very little math. Of course there's little reason to bother optimizing non-speed-crucial code.
tbl = ((0x00,)*43 + (0x33,)*43 + (0x66,)*43 +
(0x99,)*43 + (0xcc,)*43 + (0xff,)*41)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With