Closed philipwilson closed 5 years ago
Interestingly if you don't use eval
, which you should not really, there is no such issue:
print(repr(convert_color(convert_color(CMYKColor(0.75, 0.0, 0.75, 0.2), LabColor), CMYKColor)))
CMYKColor(cmyk_c=0.7499998329730001,cmyk_m=0.0,cmyk_y=0.749999613025276,cmyk_k=0.20000142321528624)
Not quite actually, defining the colour manually, e.g. new_l = LabColor(lab_l=72.31273945504653,lab_a=-66.59723871927287,lab_b=60.81823869993287)
generates the problem. The illuminants are actually different:
print(l, l.observer, l.illuminant)
print(new_l, new_l.observer, new_l.illuminant)
(LabColor(lab_l=72.31273945504653,lab_a=-66.59723871927287,lab_b=60.81823869993287), '2', 'd65')
(LabColor(lab_l=72.31273945504653,lab_a=-66.59723871927287,lab_b=60.81823869993287), '2', 'd50')
The reason as I suspected it is because the conversion path from CMYK to CIE Lab goes through the sRGB colourspace which uses D65 while the CIE Lab colours are instantiated with D50 by default:
('Converting %s to %s', LabColor(lab_l=72.31273945504653,lab_a=-66.59723871927287,lab_b=60.81823869993287), <class 'colormath.color_objects.CMYKColor'>)
(' @ Conversion path: %s', [<function Lab_to_XYZ at 0xa121aad70>, <function XYZ_to_RGB at 0xa121b3230>, <function RGB_to_CMY at 0xa121b35f0>, <function CMY_to_CMYK at 0xa121b36e0>])
(' * Conversion: %s passed to %s()', 'LabColor', <function Lab_to_XYZ at 0xa121aad70>)
(' |-> in %s', LabColor(lab_l=72.31273945504653,lab_a=-66.59723871927287,lab_b=60.81823869993287))
(' |-< out %s', XYZColor(xyz_x=0.23895088974480086,xyz_y=0.44126156667878313,xyz_z=0.07887799933599972))
(' * Conversion: %s passed to %s()', 'XYZColor', <function XYZ_to_RGB at 0xa121b3230>)
(' |-> in %s', XYZColor(xyz_x=0.23895088974480086,xyz_y=0.44126156667878313,xyz_z=0.07887799933599972))
(' \\- Target RGB space: %s', <class 'colormath.color_objects.sRGBColor'>)
(' \\- Target native illuminant: %s', 'd65')
(" \\- XYZ color's illuminant: %s", 'd50')
(' \\* Applying transformation from %s to %s ', 'd50', 'd65')
(' \\* New values: %.3f, %.3f, %.3f', 0.22315172597947527, 0.4405456503646499, 0.09880091224360746)
(' \\* Applying RGB conversion matrix: %s->%s', 'type', 'xyz_to_rgb')
(' |-< out %s', sRGBColor(rgb_r=0.0,rgb_g=0.8061322073919057,rgb_b=0.17918205240660026))
(' * Conversion: %s passed to %s()', 'sRGBColor', <function RGB_to_CMY at 0xa121b35f0>)
(' |-> in %s', sRGBColor(rgb_r=0.0,rgb_g=0.8061322073919057,rgb_b=0.17918205240660026))
(' |-< out %s', CMYColor(cmy_c=1.0,cmy_m=0.19386779260809428,cmy_y=0.8208179475933998))
(' * Conversion: %s passed to %s()', 'CMYColor', <function CMY_to_CMYK at 0xa121b36e0>)
(' |-> in %s', CMYColor(cmy_c=1.0,cmy_m=0.19386779260809428,cmy_y=0.8208179475933998))
(' |-< out %s', CMYKColor(cmyk_c=1.0,cmyk_m=0.0,cmyk_y=0.7777262206328275,cmyk_k=0.19386779260809428))
For now, you would need to explicitly instantiate with D65.
I will look at adding the observer and illuminant to the string representation and it should hopefully sort the problem.
@philipwilson : It should be fixed as per the above PR:
CMYKColor(cmyk_c=0.75, cmyk_m=0.0, cmyk_y=0.75, cmyk_k=0.2)
LabColor(lab_l=72.31273945504653, lab_a=-66.59723871927287, lab_b=60.81823869993287, observer='2', illuminant='d65')
LabColor(lab_l=72.31273945504653, lab_a=-66.59723871927287, lab_b=60.81823869993287, observer='2', illuminant='d65')
CMYKColor(cmyk_c=0.7499998329730001, cmyk_m=0.0, cmyk_y=0.749999613025276, cmyk_k=0.20000142321528624)
Thanks for the fix @KelSolaar
If I convert_colour a CYMKColor object to LabColor then back again, I get my starting CMYK values, modulo floating point noise. But if I construct a new LabColor object using the Lab* values from that conversion, then convert_color it back to CMYK, the CMYK is wrong.
There's a demo here: https://github.com/philipwilson/colormath-bug
Here's my recipe:
Note the cyan value has jumped from 0.75 to 1.0!