Convert CIE XYZ color space to RGB online with professional transformation matrix and formula. Features real-time calculation display, technical details panel, negative values detection, supports sRGB D65 standard, includes Python, JavaScript programming examples and interactive step-by-step calculations.
Perfect for color scientists, digital designers, photographers, and developers working with device-independent color, color management systems, display calibration, and accurate color reproduction. Now featuring interactive technical details panel with live matrix calculations.
This matrix converts CIE XYZ tristimulus values to linear sRGB primaries using the standard D65 illuminant (6500K daylight).
Color | X | Y | Z | RGB |
---|---|---|---|---|
Red | 41.24 | 21.26 | 1.93 | 255,0,0 |
Green | 35.76 | 71.52 | 11.92 | 0,255,0 |
Blue | 18.05 | 7.22 | 95.05 | 0,0,255 |
White D65 | 95.05 | 100.00 | 108.90 | 255,255,255 |
Black | 0.00 | 0.00 | 0.00 | 0,0,0 |
Yellow | 77.00 | 92.78 | 13.85 | 255,255,0 |
Cyan | 53.81 | 78.74 | 106.97 | 0,255,255 |
Magenta | 59.29 | 28.48 | 96.98 | 255,0,255 |
import numpy as np
# XYZ to sRGB transformation matrix
xyz_to_rgb_matrix = np.array([
[3.2406, -1.5372, -0.4986],
[-0.9689, 1.8758, 0.0415],
[0.0557, -0.2040, 1.0570]
])
def xyz_to_rgb(x, y, z):
"""Convert CIE XYZ to sRGB using D65 illuminant"""
# Current XYZ values (normalized to 0-1 range)
xyz = np.array([x/100.0, y/100.0, z/100.0])
# Matrix multiplication
rgb_linear = np.dot(xyz_to_rgb_matrix, xyz)
print(f"Linear RGB: {rgb_linear}")
# Gamma correction
def linear_to_srgb(c):
return 12.92 * c if c <= 0.0031308 else 1.055 * (c ** (1/2.4)) - 0.055
rgb_gamma = np.array([linear_to_srgb(c) for c in rgb_linear])
# Clamp to valid range and convert to 8-bit
rgb_final = np.clip(rgb_gamma * 255, 0, 255).astype(int)
print(f"Final RGB: {rgb_final}")
return tuple(rgb_final)
# Example usage
xyz = (41.24, 21.26, 1.93) # Red primary
rgb = xyz_to_rgb(*xyz)
print(f"XYZ{xyz} -> RGB{rgb}") # (255, 0, 0)
// XYZ to sRGB transformation matrix
const xyzToRgbMatrix = [
[3.2406, -1.5372, -0.4986],
[-0.9689, 1.8758, 0.0415],
[0.0557, -0.2040, 1.0570]
];
function xyzToRgb(x, y, z) {
// Current XYZ values (normalized to 0-1 range)
const xyz = [x/100.0, y/100.0, z/100.0];
// Matrix multiplication
const rgbLinear = [
xyz[0] * xyzToRgbMatrix[0][0] + xyz[1] * xyzToRgbMatrix[0][1] + xyz[2] * xyzToRgbMatrix[0][2],
xyz[0] * xyzToRgbMatrix[1][0] + xyz[1] * xyzToRgbMatrix[1][1] + xyz[2] * xyzToRgbMatrix[1][2],
xyz[0] * xyzToRgbMatrix[2][0] + xyz[1] * xyzToRgbMatrix[2][1] + xyz[2] * xyzToRgbMatrix[2][2]
];
// Gamma correction
const linearToSrgb = (c) => c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(c, 1/2.4) - 0.055;
const rgbGamma = rgbLinear.map(linearToSrgb);
// Clamp and convert to 8-bit
const rgbFinal = rgbGamma.map(c => Math.max(0, Math.min(255, Math.round(c * 255))));
console.log('Final RGB:', rgbFinal);
return rgbFinal;
}
// Example usage
const xyz = [41.24, 21.26, 1.93]; // Red primary
const rgb = xyzToRgb(...xyz);
console.log(`XYZ(${xyz.join(',')}) -> RGB(${rgb.join(',')})`);
function rgb = xyz2rgb(xyz)
% Convert CIE XYZ to sRGB (D65 illuminant)
% sRGB transformation matrix
M = [ 3.2406 -1.5372 -0.4986;
-0.9689 1.8758 0.0415;
0.0557 -0.2040 1.0570];
% Normalize XYZ values (D65 white point)
xyz_norm = xyz ./ [95.047; 100.0; 108.883];
% Matrix transformation
rgb_linear = M * xyz_norm;
% Handle negative values
rgb_linear = max(rgb_linear, 0);
% Apply gamma correction
gamma_func = @(c) ifelse(c <= 0.0031308, ...
12.92 * c, ...
1.055 * c.^(1/2.4) - 0.055);
rgb_gamma = arrayfun(gamma_func, rgb_linear);
% Scale to 0-255
rgb = round(rgb_gamma * 255);
rgb = max(0, min(255, rgb));
end
% Example usage
xyz = [41.24; 21.26; 1.93]; % Red primary
rgb = xyz2rgb(xyz);
fprintf('XYZ(%.2f,%.2f,%.2f) -> RGB(%d,%d,%d)\n', ...
xyz(1), xyz(2), xyz(3), rgb(1), rgb(2), rgb(3));
#include <algorithm>
#include <cmath>
struct RGB {
int r, g, b;
};
struct XYZ {
double x, y, z;
};
RGB xyzToRgb(const XYZ& xyz) {
// sRGB transformation matrix (D65)
const double matrix[3][3] = {
{ 3.2406, -1.5372, -0.4986},
{-0.9689, 1.8758, 0.0415},
{ 0.0557, -0.2040, 1.0570}
};
// Normalize XYZ (D65 white point)
double xn = xyz.x / 95.047;
double yn = xyz.y / 100.0;
double zn = xyz.z / 108.883;
// Matrix multiplication
double r = matrix[0][0]*xn + matrix[0][1]*yn + matrix[0][2]*zn;
double g = matrix[1][0]*xn + matrix[1][1]*yn + matrix[1][2]*zn;
double b = matrix[2][0]*xn + matrix[2][1]*yn + matrix[2][2]*zn;
// Handle negative values
r = std::max(0.0, r);
g = std::max(0.0, g);
b = std::max(0.0, b);
// Gamma correction function
auto gammaCorrect = [](double c) -> double {
if (c <= 0.0031308) {
return 12.92 * c;
} else {
return 1.055 * std::pow(c, 1.0/2.4) - 0.055;
}
};
r = gammaCorrect(r);
g = gammaCorrect(g);
b = gammaCorrect(b);
// Scale and clamp to 0-255
return {
std::max(0, std::min(255, static_cast<int>(r * 255))),
std::max(0, std::min(255, static_cast<int>(g * 255))),
std::max(0, std::min(255, static_cast<int>(b * 255)))
};
}
// Example usage
int main() {
XYZ red_xyz = {41.24, 21.26, 1.93};
RGB red_rgb = xyzToRgb(red_xyz);
printf("XYZ(%.2f,%.2f,%.2f) -> RGB(%d,%d,%d)\n",
red_xyz.x, red_xyz.y, red_xyz.z,
red_rgb.r, red_rgb.g, red_rgb.b);
return 0;
}
Different illuminants require different transformation matrices. D65 is standard for sRGB, while D50 is used for Adobe RGB and print workflows.
Used for converting between different illuminants before XYZ to RGB transformation.
Integrate this professional CIE XYZ to RGB converter into your color management system, educational platform, or scientific application:
<iframe
src="https://rgbatohex.com/tools/xyz-to-rgb-converter?embed=true"
width="100%"
height="600"
style="border:none;border-radius:12px;overflow:hidden;"
title="CIE XYZ to RGB Color Space Converter"
></iframe>
CIE XYZ is a device-independent color space based on human vision tristimulus values, representing all colors visible to the human eye. RGB is a device-dependent additive color model designed for displays and digital devices. XYZ serves as a reference standard, while RGB is optimized for practical display implementation with specific primaries and gamma correction.
Negative RGB values occur when XYZ colors are outside the sRGB gamut. Common approaches include: 1) Clipping negative values to zero (simplest), 2) Using gamut mapping algorithms to compress out-of-gamut colors, 3) Switching to a wider gamut RGB space like Adobe RGB or ProPhoto RGB, 4) Applying perceptual rendering intent to maintain color relationships while fitting within the target gamut.
The transformation matrix depends on your target RGB space and illuminant. For standard web and display work, use the sRGB D65 matrix. For print workflows, consider Adobe RGB (1998) with D65. For wide-gamut photography, use ProPhoto RGB. Always ensure the illuminant of your XYZ data matches the matrix illuminant, or apply chromatic adaptation (like Bradford transform) when necessary.
Gamma correction compensates for the non-linear response of display devices and human vision. XYZ values are linear (proportional to physical light intensity), but displays and human perception are non-linear. The sRGB gamma function (approximately 2.4) ensures that equal numeric steps in RGB produce perceptually uniform brightness changes on typical displays.
Our converter uses the standard sRGB transformation matrix with D65 illuminant, providing accuracy suitable for most color-critical applications. For maximum precision in professional workflows, consider: 1) Calibrated display profiles, 2) Appropriate illuminant matching, 3) Color management systems (CMS), 4) Measurement validation with spectrophotometers, 5) Proper handling of out-of-gamut colors through perceptual rendering.
Yes! Use NumPy for efficient batch processing. The transformation involves matrix multiplication, gamma correction, and scaling. For professional applications, consider using color science libraries like `colour-science` or `colorspacious` which handle illuminant adaptation, different RGB spaces, and advanced color management features automatically.
Our enhanced converter now includes a dedicated Technical Details panel that displays: 1) Live transformation matrix visualization, 2) Step-by-step calculation breakdown showing matrix multiplication in real-time, 3) Automatic negative value detection with warnings when colors are outside the sRGB gamut, 4) Interactive code examples for Python and JavaScript that update with current values, 5) Detailed explanation of gamma correction and range clamping processes. This makes it perfect for educational use and understanding the mathematical principles behind XYZ to RGB conversion.