To test run:
$ python test.py 96 30 -112
[27.036776088952962, 238.07024499380225, 255]
$ python test.py 20 26 -112
[0, 57.81312081380023, 225.2969485439981]
| from __future__ import division | |
| import sys | |
| def lab_to_xyz(l, a, b): | |
| ref_x = 95.047 | |
| ref_y = 100.000 | |
| ref_z = 108.883 | |
| var_y = (l + 16) / 116 | |
| var_x = a / 500 + var_y | |
| var_z = var_y - b / 200 | |
| if (pow(var_y, 3) > 0.008856): | |
| var_y = pow(var_y, 3) | |
| else: | |
| var_y = (var_y - 16 / 116) / 7.787 | |
| if (pow(var_x, 3) > 0.008856): | |
| var_x = pow(var_x, 3) | |
| else: | |
| var_x = (var_x - 16 / 116) / 7.787 | |
| if (pow(var_z, 3) > 0.008856): | |
| var_z = pow(var_z, 3) | |
| else: | |
| var_z = (var_z - 16 / 116) / 7.787 | |
| x = ref_x * var_x | |
| y = ref_y * var_y | |
| z = ref_z * var_z | |
| return (x, y, z) | |
| def xyz_to_rgb(x, y, z): | |
| var_x = x / 100 # x from 0 to 95.047 (Observer = 2, Illuminant = D65) | |
| var_y = y / 100 # y from 0 to 100.000 | |
| var_z = z / 100 # z from 0 to 108.883 | |
| var_r = var_x * 3.2406 + var_y * -1.5372 + var_z * -0.4986 | |
| var_g = var_x * -0.9689 + var_y * 1.8758 + var_z * 0.0415 | |
| var_b = var_x * 0.0557 + var_y * -0.2040 + var_z * 1.0570 | |
| if (var_r > 0.0031308): | |
| var_r = 1.055 * (pow(var_r, (1 / 2.4))) - 0.055 | |
| else: | |
| var_r = 12.92 * var_r | |
| if (var_g > 0.0031308): | |
| var_g = 1.055 * (pow(var_g, (1 / 2.4))) - 0.055 | |
| else: | |
| var_g = 12.92 * var_g | |
| if (var_b > 0.0031308): | |
| var_b = 1.055 * (pow(var_b, (1 / 2.4))) - 0.055 | |
| else: | |
| var_b = 12.92 * var_b | |
| r = var_r * 255 | |
| g = var_g * 255 | |
| b = var_b * 255 | |
| def limit(value): | |
| if value < 0: | |
| return 0 | |
| elif value > 255: | |
| return 255 | |
| else: | |
| return value | |
| return map(limit, (r, g, b)) | |
| if __name__ == '__main__': | |
| xyz = lab_to_xyz(*map(int, sys.argv[1:4])) | |
| print('xyz: %s' % xyz) | |
| print('rgb: %s' % xyz_to_rgb(*xyz)) |