noumenal noumenal - 5 months ago 13x
Python Question

CIELAB is gain saturating when converting to float sRGB

I am using colormatch for python to convert CIE L*a*b* to sRGB




(1.0458503175786145, 0.47183611022803823, 0.682521668019042)

However, 1.045... is out of range by 12 bytes. Is this expected behavior?


The gamut of L*a*b* is wider than sRGB, so the conversion overflowing is normal.

L*a*b* can represent every perceivable color but sRGB within the 0 ≤ r,g,b ≤ 1 range is only a small subset. Your color is just outside of this subset.

(See also Boundaries of the visible gamut in a CIE color space)

If you don't like overflowing, in colormath you could use the clamped_rgb_r, etc properties to get the value clipped in the range [0.0, 1.0], as explained in the documentation on Color Conversion:

RGB spaces tend to have a smaller gamut than some of the CIE color spaces. When converting to RGB, this can cause some of the coordinates to end up being out of the acceptable range (0.0-1.0 or 1-255, depending on whether your RGB color is upscaled).

Rather than clamp these for you, we leave them as-is. This allows for more accurate conversions back to the CIE color spaces. If you require the clamped (0.0-1.0 or 1-255) values, use the following properties on any RGB color:

  • clamped_rgb_r
  • clamped_rgb_g
  • clamped_rgb_b


from colormath import color_objects, color_conversions

lab_color = color_objects.LabColor(lab_l=70.0, lab_a=60.0, lab_b=0.0)
rgb_color = color_conversions.convert_color(lab_color, color_objects.sRGBColor)
# sRGBColor(rgb_r=1.045850317578614,rgb_g=0.47183611022803845,rgb_b=0.6825216680190419)
print((rgb_color.clamped_rgb_r, rgb_color.clamped_rgb_g, rgb_color.clamped_rgb_b))
# (1.0, 0.47183611022803845, 0.6825216680190419)