alvas
alvas

Reputation: 121992

How to convert RGB percentage to RGB values?

Given the RGB percentages of a color, e.g. "wild watermelon", (99%, 42%, 52%), the right RGB values are (252, 108, 133).

But when I tried

rgb_percent = ('99%', '42%','52%')
rgb_values = tuple(int(int(s.strip('%')) * 2.55) for s in rgb_percent)
print(rgb_values)

[out]:

(252, 107, 132)

The color looks similar but they are not the right values. How to convert RGB percentage to RGB values correctly?

Should I be rounding up/down them instead or casting the values to integer? This seems closer but not the expected values still:

tuple(int(round(int(s.strip('%')) * 2.55, 0)) for s in rgb_percent)

[out]:

(252, 107, 133)

Upvotes: 0

Views: 2823

Answers (3)

Suat Atan PhD
Suat Atan PhD

Reputation: 1372

Instead of rediscovering the nature of different color codes I researched the packages and find one usable and detailed package for this. When we look at the code of this package similar problems have been mentioned and solved. With this package with the help of bit reverse engineering I found this way:

#pip install webcolors #to install
import webcolors as wco
hex = wco.rgb_percent_to_hex(('99%','42%','52%'))
wco.hex_to_rgb(hex)

Resut is IntegerRGB(red=252, green=107, blue=133).

Although there is no rgb_percent_to_rgb function instead of this I converted percentage values to HEX and then converted them to values.

Upvotes: 1

Giacomo Catenazzi
Giacomo Catenazzi

Reputation: 9523

You cannot get exactly the same values, because you round numbers. 100 and 255 are not multiples. Your percentage RGB seems to be all integer, so you lost at minimum 1 bit of information (and possibly also 2 bits). So you cannot expect exact values on all cases. (You cannot map 100 numbers into 256 values, and get all 256 values).

But the good: you do not need it (usually). Your eyes are not so sensible (and we cannot see all combination of RGB with 256x256x256 values: our eyes can distinguish a lot less colours, so on some case you will see no differences, and on some, it is just barely noticeable). In addition some monitor panel trick displaying only 64 different shades per channel (and few people notice it). Consider that if you took data from a JPEG image, you get an additional conversion (data are not stored as RGB data, but as YCC).

To get the best choice, you need to know the original algorithm (do they round or trunc? or you should have a larger example test, and check the differences between different algorithms (e.g. how many cases are precise, how many are just 1 off, 2 off, 3 off).

Note: you have 3 possibilities: round(), math.floor(), and math.ceil(). I would avoid using int: according Python documentation, it seems the result depend on the system standard library (it could be truncated, or rounded). Note: math.trunc() and math.floor() gives the same results for positive (or zero) numbers.

In general, I would prefer round: it gives expected results for 0% and 100% (ceil is similar for these extreme values).

PS: there is not "correct RGB values". Historically RGB were given as numbers from 0 to 100 (and possibly as floating point number), or from 0.0 to 1.0. Just HTML pushed for 0 to 255, but it causes problems if you have a screens which can display more colours. And probably for RGB you mean R*G*B*, so not a linear RGB, but a OETF corrected RGB).

And no: there is not reputable sources. Nobody follows standards, so do not expect people which converted the colour channel (e.g. to 99%) are using exact the same method (we programmers are lazy). And standards tend to uses floating points. Note: internally a program may use floating point numbers, so in a colour picker you may get different colours with same displayed %-values, depending on how you input the colour. Or do you refer to a specific standard which specifies %-values? We cannot agree if black is 0,0,0 or 16,16,16 (e.g. MPEG-2, or TVs, and other limited range RGB devices), or how do do or interpret the gamma correction (ok: recent and less-recent standards are more precise, but most programs didn't get it). Also when reading your "RGB" values, in past I would assume it would be sRGB (so colour space of web and Microsoft), but since few years Apple use a different colour space (Apple P3), and other are following extending sRGB. Chaos. So just test different methods (and use your eyes to check quality).

Upvotes: 5

Maxwell D. Dorliea
Maxwell D. Dorliea

Reputation: 1302

Yes, round up before casting them to int values but remember float values aren't precise so you won't always get the expected output

Upvotes: 0

Related Questions