MeatColor::summarize_lab() converts mean CIELAB coordinates with:
colorspace::hex(colorspace::LAB(L, a, b))The conversion path is CIELAB → CIEXYZ → linear-light sRGB → encoded sRGB → hexadecimal.
This calculation assumes:
- the input is CIE 1976 L*a*b* (CIELAB), not Hunter Lab;
- the CIELAB values use the same D65/2° reference white as the
colorspacepackage default; and - the intended output is the sRGB display color space.
Colorimeter exports can depend on illuminant, observer angle, and color-space settings. Confirm that the instrument exported CIELAB values under D65 with the 2° standard observer before interpreting the generated hex values as sRGB. Values measured relative to another white point or observer require an appropriate conversion before the sRGB matrix is applied.
For CIELAB coordinates
Use the exact CIELAB constants:
The inverse CIELAB transfer function is:
The relative tristimulus values are:
The boundary
For the D65 reference white used by colorspace, scaled so
Then:
XYZ components are not each restricted to
The colorspace implementation uses XYZ values scaled to
Here
For each linear-light component
The current colorspace C implementation uses 0.00304 as its branch
threshold. This small implementation difference does not affect the worked
example below, but the formula above gives the standard sRGB threshold.
For an in-gamut encoded component
Each resulting integer is written as a two-digit hexadecimal value and concatenated:
hex = #RRGGBB
MeatColor currently calls colorspace::hex() with its default
fixup = FALSE. Therefore, if any rounded component lies outside 0–255,
colorspace returns NA rather than clipping the color. Calling
colorspace::hex(..., fixup = TRUE) would instead clamp out-of-range
components to the nearest endpoint.
First:
All three values use the cubic branch:
Scaling by the D65 reference white gives:
Using the matrix implemented by colorspace gives linear-light sRGB:
After sRGB encoding:
Quantizing to 8-bit components gives:
Therefore:
Result: #8D69A2
This result matches:
colorspace::hex(colorspace::LAB(50, 25, -25))
#> "#8D69A2"- A screen swatch is an sRGB approximation of measured color, not a color-managed reproduction of the physical meat sample.
- CIELAB coordinates are meaningful only with their reference illuminant, observer, and measurement geometry.
- Out-of-gamut CIELAB colors cannot be represented exactly in sRGB.
- Keep full precision through the intermediate calculations and round only when producing the final 8-bit channels.