XYZ to RGB Converter - Free CIE XYZ Color Space Transformation Tool

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.

XYZ to RGB Transformation Matrix & Formula

sRGB D65 Transformation Matrix

Linear RGB = M × XYZ
⎡R⎤ ⎡ 3.2406 -1.5372 -0.4986⎤ ⎡X⎤
⎢G⎥ = ⎢-0.9689 1.8758 0.0415⎥ ⎢Y⎥
⎣B⎦ ⎣ 0.0557 -0.2040 1.0570⎦ ⎣Z⎦

This matrix converts CIE XYZ tristimulus values to linear sRGB primaries using the standard D65 illuminant (6500K daylight).

Step-by-Step Conversion Process

1. Matrix Multiplication:
R_linear = 3.2406×X - 1.5372×Y - 0.4986×Z
G_linear = -0.9689×X + 1.8758×Y + 0.0415×Z
B_linear = 0.0557×X - 0.2040×Y + 1.0570×Z
2. Gamma Correction (sRGB):
if (linear ≤ 0.0031308):
  sRGB = 12.92 × linear
else:
  sRGB = 1.055 × linear^(1/2.4) - 0.055
3. Range Clamping:
RGB = clamp(sRGB × 255, 0, 255)

Example Calculation: XYZ(41.24, 21.26, 1.93)

Matrix Multiplication:
R = 3.2406×41.24 - 1.5372×21.26 - 0.4986×1.93
R = 133.68 - 32.69 - 0.96 = 100.03
G = -0.9689×41.24 + 1.8758×21.26 + 0.0415×1.93
G = -39.95 + 39.87 + 0.08 = 0.00
B = 0.0557×41.24 - 0.2040×21.26 + 1.0570×1.93
B = 2.30 - 4.34 + 2.04 = 0.00
Gamma & Scale:
R = 1.055 × (1.0003)^(1/2.4) - 0.055 = 1.0
RGB(255, 0, 0) - Pure Red

XYZ to RGB Reference Values & Standards

sRGB Primary Colors (D65)

ColorXYZRGB
Red41.2421.261.93255,0,0
Green35.7671.5211.920,255,0
Blue18.057.2295.050,0,255
White D6595.05100.00108.90255,255,255
Black0.000.000.000,0,0
Yellow77.0092.7813.85255,255,0
Cyan53.8178.74106.970,255,255
Magenta59.2928.4896.98255,0,255

XYZ Value Ranges & Limits

Standard D65 Ranges:

X: 0.0 - 95.047 (typical range)
Y: 0.0 - 100.0 (luminance)
Z: 0.0 - 108.883 (typical range)

Handling Negative Values:

• Negative XYZ values can occur with certain illuminants
• Matrix multiplication may produce negative RGB
• Clamp negative values to 0 for display
• Use specialized color management for extreme cases

Out-of-Gamut Colors:

• XYZ can represent colors outside sRGB gamut
• RGB values > 255 indicate out-of-gamut
• Apply gamut mapping or clipping as needed

XYZ to RGB Programming Implementation

🐍Python - XYZ to RGB Conversion

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)

JavaScript - XYZ to RGB Conversion

// 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(',')})`);

📊MATLAB - XYZ to RGB Conversion

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));

⚙️C++ - XYZ to RGB Conversion

#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;
}

Advanced XYZ to RGB Color Science

Illuminants & White Points

Standard Illuminants:

D65 (6500K): X=95.047, Y=100.000, Z=108.883
D50 (5000K): X=96.422, Y=100.000, Z=82.521
A (2856K): X=109.850, Y=100.000, Z=35.585
E (Equal): X=100.000, Y=100.000, Z=100.000

Different illuminants require different transformation matrices. D65 is standard for sRGB, while D50 is used for Adobe RGB and print workflows.

Color Gamuts & RGB Spaces

sRGB (Standard RGB)

Coverage: ~35% of visible spectrum
Gamma: 2.4 (with linear segment)

Adobe RGB (1998)

Coverage: ~50% of visible spectrum
Better for print workflows

ProPhoto RGB

Coverage: ~90% of visible spectrum
Professional photography

Chromatic Adaptation

Bradford Transform

⎡ 0.8951 0.2664 -0.1614⎤
⎢-0.7502 1.7135 0.0367⎥
⎣ 0.0389 -0.0685 1.0296⎦

Used for converting between different illuminants before XYZ to RGB transformation.

Handling Out-of-Gamut Colors

Clipping Method

Simply clamp RGB values to 0-255 range
⚠ May cause color shifts

Perceptual Rendering

Compress entire color range proportionally
✓ Maintains color relationships

Relative Colorimetric

Map out-of-gamut to gamut boundary
→ Preserves in-gamut colors exactly

Negative RGB Values

Causes:
• XYZ colors outside RGB gamut
• Imaginary colors from spectral data
• Measurement errors in colorimetry
Solutions:
• Clamp to zero (simplest)
• Use wider gamut RGB space
• Apply gamut mapping algorithms

Embed This XYZ to RGB Converter

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>

XYZ to RGB Conversion - Frequently Asked Questions

What is the difference between CIE XYZ and RGB color spaces?

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.

How do you handle negative RGB values in XYZ to RGB conversion?

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.

Which transformation matrix should I use for XYZ to RGB conversion?

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.

Why is gamma correction necessary in XYZ to RGB conversion?

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.

How accurate is the XYZ to RGB conversion for color-critical applications?

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.

Can I convert XYZ to RGB in Python for batch processing?

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.

What are the new technical details and real-time calculation features?

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.

xyz to rgbxyz to rgb matrixxyz to rgb formulaxyz to rgb conversionxyz to rgb onlinexyz to rgb converterxyz to rgb negative valuesxyz to rgb transformation matrixxyz to rgb pythonCIE XYZsRGB D65color space conversiongamma correctionchromatic adaptationreal-time calculationtechnical details panelinteractive matrix visualizationlive color conversion