Converting HEX colors to blender RGB

I’ve looked into this for days now, and can’t figure it out even after extensive googling and looking through blenders sourcecode.

My objective is to take a HEX color and translate that to blender-rgb through a python-script.
So far, I’ve tried calculating the blender-RGB-value (3 decimals ranging from 0 to 1) from the hex color by converting HEX to normal RGB (0 to 255) first, and then dividing it by 255, as such:

[TABLE=“class: grid, width: 500”]

Original input ( a nice shade of blue ):
0033ff

Converting this to normal RGB (0-255):
0, 51, 255

Dividing each number through 255 to get blenderRGB:
0, 0.2, 1

[/TABLE]

However the blender-RGB: (0, 0.2, 1) isn’t the same color as where we started off from. Any suggestions? What am I missing?

If I input the HEX-color ‘0033ff’ in blenders colorpicker directly, it translated to (0, 0.0331, 1), which IS the right color. Only problem is… I need to do it programatically. Please help me, I ran into a mountain here.
See attachment for the color difference (left: wrong color, right: correct color (0033ff)).

Attachments


that difference is probably caused by gamma correction. Not sure how to calculate this in python…

Maybe have a look at the C code and re-create something with py, e.g.
blender\source\blender\blenlib\intern\math_color.c

Thank you for your reply, I think your idea that it’s gamma correction is spot on, since in the blender color picker it says; “gamma corrected”. I don’t know C, but i’ll try to figure out if the calculation is different from mine. Do you reckon it’s this function that holds the secret?:

void hex_to_rgb(char *hexcol, float *r, float *g, float *b)
{
unsigned int ri, gi, bi;

if (hexcol[0] == ‘#’) hexcol++;

if (sscanf(hexcol, “%02x%02x%02x”, &ri, &gi, &bi)==3) {
*r = ri / 255.0f;
*g = gi / 255.0f;
*b = bi / 255.0f;
CLAMP(*r, 0.0f, 1.0f);
CLAMP(*g, 0.0f, 1.0f);
CLAMP(b, 0.0f, 1.0f);
}
else {
/
avoid using un-initialized vars */
*r= *g= *b= 0.0f;
}
}

It is the Display Device setting under the Scene context. Change it from sRGB to None and your color numbers will make senses.

You may be able to programatically change it to None, issue your calculation, assign the color and change it back to whatever it was set to.

Example:

import bpy

def hex_to_rgb(color_str):
    # supports '123456', '#123456' and '0x123456'
    (r,g,b), a = map(lambda component: component / 255, bytes.fromhex(color_str[-6:])), 1.0
    return (r,g,b,a)
    
sce = bpy.context.scene
ob = bpy.context.object

display_device = sce.display_settings.display_device
sce.display_settings.display_device = 'None'
ob.color = hex_to_rgb("0033ff")
sce.display_settings.display_device = display_device

Hm… for some reason, there’s a different result if e.g. Rec was used as color management (006FFF vs. 007CFF if it was sRGB) :frowning:

This did the trick, THANKS ALOT :smiley: It got me dragging for days.

Can i ask why blender uses this weird system for color numbers. Why do we need to convert them, almost all applications use regular RGB numbers not a divided version of 255???

1 Like

Can i ask why blender uses this weird system for color numbers.

a) expressing colors as floats in the range 0…1 is pretty common, not weird.
b) In Blender, it makes sense in some places to be able to enter color values higher than 1.0 (which is called HDR)

But i dont understand why one would use float numbers for these. If you check items from other apps you always need to convert this to a number. Ridiculous!