Search code examples
javascriptrgb

RGB to XYZ and LAB colours conversion


I'm having problems converting colours from RGB to LAB space It should be straight forward using the formulas from here, only I'm getting back the wrong values

  • RGB = 56,79,132

  • X = 8.592

  • Y = 8.099
  • Z = 22.940

and CIE-L*ab as

  • L* 34.188
  • a* 8.072
  • b* -32.478

This is my code; but I can't see where I'm going wrong. It maybe due to floating points like this fella before me. Thank you.

// user colour
var Red   = 56;
var Green = 79;
var Blue  = 132;

// user colour converted to XYZ space
XYZ = RGBtoXYZ(Red,Green,Blue)
var colX = XYZ[0];
var colY = XYZ[1];
var colZ = XYZ[2];

// alert(XYZ)

LAB = XYZtoLAB(colX, colY, colZ)

alert(LAB)

function RGBtoXYZ(R, G, B)
{
    var_R = parseFloat( R / 255 )        //R from 0 to 255
    var_G = parseFloat( G / 255 )        //G from 0 to 255
    var_B = parseFloat( B / 255 )        //B from 0 to 255

    if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4
    else                   var_R = var_R / 12.92
    if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4
    else                   var_G = var_G / 12.92
    if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4
    else                   var_B = var_B / 12.92

    var_R = var_R * 100
    var_G = var_G * 100
    var_B = var_B * 100

    //Observer. = 2°, Illuminant = D65
    X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
    Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
    Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
    return [X, Y, Z]
}


function XYZtoLAB(x, y, z)
{
    var ref_X =  95.047;
    var ref_Y = 100.000;
    var ref_Z = 108.883;

    var_X = x / ref_X          //ref_X =  95.047   Observer= 2°, Illuminant= D65
    var_Y = y / ref_Y          //ref_Y = 100.000
    var_Z = z / ref_Z          //ref_Z = 108.883

    if ( var_X > 0.008856 ) var_X = var_X ^ ( 1/3 )
    else                    var_X = ( 7.787 * var_X ) + ( 16 / 116 )
    if ( var_Y > 0.008856 ) var_Y = var_Y ^ ( 1/3 )
    else                    var_Y = ( 7.787 * var_Y ) + ( 16 / 116 )
    if ( var_Z > 0.008856 ) var_Z = var_Z ^ ( 1/3 )
    else                    var_Z = ( 7.787 * var_Z ) + ( 16 / 116 )

    CIE_L = ( 116 * var_Y ) - 16
    CIE_a = 500 * ( var_X - var_Y )
    CIE_b = 200 * ( var_Y - var_Z )

return [CIE_L, CIE_a, CIE_b]
}

Solution

  • I'm pretty sure ^ is bitwise xor in javascript not a power operator. I think Math.pow is what you are looking for.