4
$\begingroup$

I am trying to get a hex value out of material color. I find an reply here by @douripo: Get Hex triplet for color and real 256 RGB from diffuse Color using python

it successfully converts most of the colors to hex correctly. except a few. here is an example it does not convert right.

in blender, add a material to default cube and manually set its diffuse_color to hex 60590A (brown-ish yellow)

run below code in text editor, it would return 6059AA (purple-ish blue). could anyone check where went wrong? and hopefully a fix?

import bpy import math #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$
3
  • $\begingroup$ 1% is a gross exaggeration: with just integers for colors it would be 16 / 256 cubed or less than one ten thousands of one percent of all possible colors.... , lol. Good spot. IIRC there is another answer re this converting both ways. ... actually prob less, 15 numerator since zero 00 would have worked as expected too. $\endgroup$ Commented Aug 15, 2021 at 7:54
  • 1
    $\begingroup$ That's counting colors where every RGB value is wrong, It's more like 17% where at least one RGB value is wrong. $\endgroup$ Commented Aug 15, 2021 at 8:09
  • 1
    $\begingroup$ @scurest No doubt it's OR ie 3 * 15 / 256 .. not AND never was good at stats $\endgroup$ Commented Aug 15, 2021 at 8:47

1 Answer 1

13
$\begingroup$

The issue occurs when str(to_hex(rgb[i]))[2:] returns a length 1 value, which is the case for blue in example given "0xa".

 if len(val) == 1: val += val 

incorrectly turning it into "aa" instead of "0a". Using val = "0" + val will correct the issue. Another option, used below, is string formatting to convert an integer i into a zero padded length 2 hex string "%02x" % i

Here's a cleaned up version:

def linear_to_srgb8(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 if srgb > 1: srgb = 1 return round(255*srgb) def toHex(r, g, b): return "%02x%02x%02x" % ( linear_to_srgb8(r), linear_to_srgb8(g), linear_to_srgb8(b), ) 
$\endgroup$
1
  • $\begingroup$ Fantastic !!! it works like a charm. thank you so very much for pointing it out and fixing it. $\endgroup$ Commented Aug 15, 2021 at 18:40

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.