1
$\begingroup$

as you know the RGB structure each parameter (red, green, and blue) defines the intensity of the color as an integer between 0 and 255., Actually, in Blender, you have that in sRGB, then any traditional convertion to HEX work BECAUSE the Hex in blender is GAMMA CORRECTED.

also in Documentation I can NOT get any reference about how get the HEX TRIPLE FOR COLOR CODE ...

RGB HEX GAMMA CORRECTED

how to get both with python?

UPDATE:

I want the hex value or how convert the hex to RGB

AS @dr.Sybren I thougth That was just a straight conversion of the bytes in RGB order converted to hexadecimal notation, and then tried some simple code as @tet_ii

context = bpy.context
obj = context.object

color_inferior= obj.material_slots['inferior'].material.diffuse_color


a = '#%02x%02x%02x' % (int(255.999 * pow(color_inferior.r, 1/2.2)),int(255.999 * pow(color_inferior.g, 1/2.2)),int(255.999 * pow(color_inferior.b, 1/2.2)))    

print(a)

testing the code I got:

rgb to hex convertion

also, I test other codes with the same or worst result:

https://stackoverflow.com/questions/3380726/converting-a-rgb-color-tuple-to-a-six-digit-code-in-python

then. Can I capture the value directly from blender without any convertion? or do a 100% accurate conversion?

$\endgroup$
9
  • $\begingroup$ What are you asking exactly? How to gamma-correct a colour? Or how to convert an RGBA value to hexadecimal notation? $\endgroup$
    – dr. Sybren
    Nov 27, 2017 at 22:54
  • $\begingroup$ @dr.Sybren I want the hex value or how convert the hex to RGB $\endgroup$
    – yhoyo
    Nov 27, 2017 at 22:55
  • $\begingroup$ That's just a straight conversion of the bytes in RGB order converted to hexadecimal notation. The digits are then RRBBGG, where each letter represents 4 of the 8 bits that make up a byte. $\endgroup$
    – dr. Sybren
    Nov 27, 2017 at 22:59
  • $\begingroup$ @dr.Sybren I thought that too. But No... Or something I'm doing wrong $\endgroup$
    – yhoyo
    Nov 27, 2017 at 23:01
  • $\begingroup$ Then describe what you are doing, instead of shouting (uppercase letters means shouting) that things don't work. Give us the math you're applying, the results you get, and the results you expected. $\endgroup$
    – dr. Sybren
    Nov 27, 2017 at 23:48

3 Answers 3

2
$\begingroup$

This code adapted from devtalk.blender.org, convert color from blender standard active material to hex.

import bpy

#code by : brecht - devtalk.blender.org
def to_hex(c):
    if c < 0.0031308:
        srgb = 0.0 if c < 0.0 else c * 12.92
    else:
        srgb = 1.055 * math.pow(c, 1.0 / 2.4) - 0.055

    return hex(max(min(int(srgb * 255 + 0.5), 255), 0))

def toHex(r,g,b):
    rgb = [r,g,b]
    result = ""
    i=0
    while i < 3:
        val = str(to_hex(rgb[i]))
        val = val[2:]
        if len(val) == 1:
            val += val
        result+=val
        i+=1
    return result

ob = bpy.context.object
color_inferior = ob.active_material.diffuse_color

a = toHex(color_inferior[0],color_inferior[1],color_inferior[2])

print (a)
$\endgroup$
1
0
$\begingroup$

Try turn off color manager for display device:

bpy.context.scene.display_settings.display_device = 'None'

After, color circle give value 0xCA0001 for 0.791; 0.000; 0.003

$\endgroup$
0
$\begingroup$

To get something closer, I actually think that @Chau answer is relevant in the sense that we need to convert the colors from and back linear sRGB format (see this formula).

In fact I can somewhat get the same colors by doing:

import bpy

# run with exec(bpy.data.texts['convert.py'].as_string())

REPLACE_MAP = {
    '787859': 'B34CB3',
}

def srgb_to_linear(color):
    def color_conversion(c):
        if c <= 0.0404482362771082:
            return c / 12.92
        else:
            return ((c + 0.055) / 1.055) ** 2.4

    return list(map(lambda c: color_conversion(c), color[:3])) + [color[-1]]

def linear_to_srgb(color):
    def color_conversion(c):
        if c <= 0.00313066844250063:
            return c * 12.92
        else:
            return 1.055 * (c ** (1/2.4)) - 0.055

    return list(map(lambda c: color_conversion(c), color[:3])) + [color[-1]]

def hex_to_rgba(color_str):
    # supports '123456', '#123456' and '0x123456'
    (r,g,b), a = map(lambda c: c / 255, bytes.fromhex(color_str[-6:])), 1.0
    return (r,g,b,a)

def rgba_to_hex(color, alpha=False):
    rgba = ''.join(map(lambda c: "{:02x}".format(round(c * 255)), color))
    return rgba[:0 if alpha else -2].upper()

color = bpy.data.materials[-1].diffuse_color
(r,g,b,a) = color
linear = linear_to_srgb(color)
hex = rgba_to_hex(linear)
new_color = srgb_to_linear(hex_to_rgba(hex))

print('Initial color', r,g,b,a)
print('Linear', linear)
print('To hex', hex)
print('To color again', new_color)

color = hex_to_rgba("E95420")
(r,g,b,a) = color
print('from hex E95420', r,g,b,a)
print('to hex', rgba_to_hex(color))

Which results in:

>>> exec(bpy.data.texts['convert.py'].as_string())
Initial color 0.31398871541023254 0.533276379108429 0.8796223998069763 1.0
Linear [0.5960784331303468, 0.7568627293017685, 0.9450980405985859, 1.0]
To hex 98C1F1
To color again [0.31398871337571754, 0.5332764040105052, 0.8796223968878317, 1.0]
from hex E95420 0.9137254901960784 0.32941176470588235 0.12549019607843137 1.0
to hex E95420
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .