latex3 / xcolor

Driver-independent color extensions for LaTeX and pdfLaTeX
LaTeX Project Public License v1.3c
28 stars 5 forks source link

Support HCL colors #26

Closed ttusar closed 1 year ago

ttusar commented 1 year ago

Is there any plan to support HCL color spaces? They are perceptually uniform and can be used to create color maps like these:

image (from https://hclwizard.org/)

Ideally, a color map (such as Viridis) would first be initialized and then used it in a table to color the background of the cells according to their values.

u-fischer commented 1 year ago

for PDF the colors must at the end be converted into rgb or cmyk. So if you want that, please provide a suitable converter function (with a reliable source as a reference). See https://github.com/latex3/xcolor/issues/25 for an example.

ttusar commented 1 year ago

According to https://www.easyrgb.com/en/math.php, it seems that a CIE-L*uv color can be converted to RGB via CIE XYZ as follows:

*CIE-Luv → XYZ**

//Reference-X, Y and Z refer to specific illuminants and observers.
//Common reference values are available below in this same page.

var_Y = ( CIE-L* + 16 ) /116
if ( var_Y^3  > 0.008856 ) var_Y = var_Y^3
else                       var_Y = ( var_Y - 16 / 116 ) / 7.787

ref_U = ( 4 * Reference-X ) / ( Reference-X + ( 15 * Reference-Y ) + ( 3 * Reference-Z ) )
ref_V = ( 9 * Reference-Y ) / ( Reference-X + ( 15 * Reference-Y ) + ( 3 * Reference-Z ) )

var_U = CIE-u* / ( 13 * CIE-L* ) + ref_U
var_V = CIE-v* / ( 13 * CIE-L* ) + ref_V

Y = var_Y * 100
X =  - ( 9 * Y * var_U ) / ( ( var_U - 4 ) * var_V - var_U * var_V )
Z = ( 9 * Y - ( 15 * var_V * Y ) - ( var_V * X ) ) / ( 3 * var_V )

XYZ → Standard-RGB

//X, Y and Z input refer to a D65/2° standard illuminant.
//sR, sG and sB (standard RGB) output range = 0 ÷ 255

var_X = X / 100
var_Y = Y / 100
var_Z = Z / 100

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 * ( var_R ^ ( 1 / 2.4 ) ) - 0.055
else                     var_R = 12.92 * var_R
if ( var_G > 0.0031308 ) var_G = 1.055 * ( var_G ^ ( 1 / 2.4 ) ) - 0.055
else                     var_G = 12.92 * var_G
if ( var_B > 0.0031308 ) var_B = 1.055 * ( var_B ^ ( 1 / 2.4 ) ) - 0.055
else                     var_B = 12.92 * var_B

sR = var_R * 255
sG = var_G * 255
sB = var_B * 255
XYZ (Tristimulus) Reference values of a perfect reflecting diffuser Illuminant [Observer] X2
[2° (CIE 1931)]
Y2
[2° (CIE 1931)]
Z2
[2° (CIE 1931)]
X10
[10° (CIE 1964)]
Y10
[10° (CIE 1964)]
Z10
[10° (CIE 1964)]
Note
A 109.850 100.000 35.585 111.144 100.000 35.200 Incandescent/tungsten
B 99.0927 100.000 85.313 99.178; 100.000 84.3493 Old direct sunlight at noon
C 98.074 100.000 118.232 97.285 100.000 116.145 Old daylight
D50 96.422 100.000 82.521 96.720 100.000 81.427 ICC profile PCS
D55 95.682 100.000 92.149 95.799 100.000 90.926 Mid-morning daylight
D65 95.047 100.000 108.883 94.811 100.000 107.304 Daylight, sRGB, Adobe-RGB
D75 94.972 100.000 122.638 94.416 100.000 120.641 North sky daylight
E 100.000 100.000 100.000 100.000 100.000 100.000 Equal energy
F1 92.834 100.000 103.665 94.791 100.000 103.191 Daylight Fluorescent
F2 99.187 100.000 67.395 103.280 100.000 69.026 Cool fluorescent
F3 103.754 100.000 49.861 108.968 100.000 51.965 White Fluorescent
F4 109.147 100.000 38.813 114.961 100.000 40.963 Warm White Fluorescent
F5 90.872 100.000 98.723 93.369 100.000 98.636 Daylight Fluorescent
F6 97.309 100.000 60.191 102.148 100.000 62.074 Lite White Fluorescent
F7 95.044 100.000 108.755 95.792 100.000 107.687 Daylight fluorescent, D65 simulator
F8 96.413 100.000 82.333 97.115 100.000 81.135 Sylvania F40, D50 simulator
F9 100.365 100.000 67.868 102.116 100.000 67.826 Cool White Fluorescent
F10 96.174 100.000 81.712 99.001 100.000 83.134 Ultralume 50, Philips TL85
F11 100.966 100.000 64.370 103.866 100.000 65.627 Ultralume 40, Philips TL84
F12 108.046 100.000 39.228 111.428 100.000 40.353 Ultralume 30, Philips TL83
u-fischer commented 1 year ago

Sorry but I don't have the time to write a converter function. If you want it, please implement it and make a suitable pull request or at least a small exampl.e

ttusar commented 1 year ago

I'm afraid writing a function similar to the example from #25 is beyond what I am able to do.

u-fischer commented 1 year ago

Then I will close this issue for now. It can be reopened if someone offers some code.

zauguin commented 1 year ago

@ttusar If you are using LuaTeX then you can use https://github.com/zauguin/luaicc for such maps.

ttusar commented 1 year ago

I will have a look, thanks @zauguin for the pointer

ttusar commented 1 year ago

To anyone else stumbling over this issue, there is now an example on Overleaf that builds on the code provided by @zauguin. Hopefully it will be of help to someone.