Skip to main content
scotwllm
Inspiring
December 6, 2024
Question

How does Photoshop calculate Lab values?

  • December 6, 2024
  • 5 replies
  • 4442 views

In the Color Picker tool, Photoshop presents the Lab values of colors if you type in the RGB or HSB values. 

I doubt Adobe goes to one of the color conversion websites to get the Lab values. Does anybody know the formula they use to calculate it?

 

Scott

This topic has been closed for replies.

5 replies

Conrad_C
Community Expert
December 8, 2024

It might help to understand the quote below from the book “Real World Photoshop CS3” which was published in 2008. It also appeared in the book’s earlier editions by the late Bruce Fraser, as well as his book “Real World Color Management” published in 2003. Bruce didn’t just say that out of thin air. He worked closely with the Photoshop team.

 

 

The second quote, below, is from page 33 of “The Digital Print” (2014) by Jeff Schewe, who also works closely with the Photoshop, Camera Raw, and Lightroom teams.

 

 

Anyone who studies how Photoshop color works eventually understands that: 

  • Lab is its reference color space for color conversions.
  • Any color conversions must be corrected for the specific color space of the current color mode (such as sRGB vs Adobe RGB, or FOGRA CMYK vs US SWOP CMYK). 

 

If you show an Excel spreadsheet or color conversion table that doesn’t account for color space, or doesn’t use Lab as a reference color space, that conversion table is not useful or reliable when discussing Photoshop.

davescm
Community Expert
December 8, 2024

I would take that one step further:

'If you show an Excel spreadsheet or color conversion table that doesn’t account for color space, or doesn’t use Lab as a reference color space, that conversion table is not useful or reliable' when discussing Photoshop.

Dave

scotwllm
scotwllmAuthor
Inspiring
December 8, 2024

I found the answer. 

c.pfaffenbichler
Community Expert
December 8, 2024
quote

I found the answer. 


By @scotwllm

Does that actually honor the RGB Color Space? 

D Fosse
Community Expert
December 6, 2024

Stephen Marsh
Community Expert
December 6, 2024

Colour management.

 

Make 2 separate RGB files, one sRGB, the other ProPhoto RGB. Type in the same set of RGB values and compare the Lab readings. Type in the same Lab values and compare the RGB readings.

D Fosse
Community Expert
December 6, 2024

It's the other way round. All color space numbers are calculated from Lab.

 

Lab is the reference and at the base of all color management. It is one of two commonly used Profile Connection Spaces (the other is CIE XYZ).

 

A standard profile conversion goes, say, Adobe RGB > Lab > sRGB.

 

Lab numbers define a color absolutely.

scotwllm
scotwllmAuthor
Inspiring
December 8, 2024

Hi there --

 

I appreciate the time you invested to respond to my question.  However, you answered a question I didn't ask. I asked how does Photoshop calculate the numbers that appear in the color picker when a user enters RGB values. I've found formulas online that purport to do it, but they're written in code or use calculus. I took calculus around 40 years ago and have never needed to use it until now. I need to calculate the Delta-E between multiple colors, and plugging them into a website form one by one takes too much time. I'm too old to waste it on that kind of stuff, know what I mean?

Stephen Marsh
Community Expert
December 9, 2024
quote

I need to calculate the Delta-E between multiple colors, and plugging them into a website form one by one takes too much time. I'm too old to waste it on that kind of stuff, know what I mean?


By @scotwllm

 

Which dE: de76/dEab, dE94 etc?

 

If the formula can be translated into JavaScript, there may be a way to do this...

 

I'm sure you know of the following:

 

http://www.brucelindbloom.com/index.html?Calc.html


The following three scripts provide a rough dE evaluation between the foreground and background colour picker values.

 

 

 

 

/*
    Calculates the CIE76 (dE76) color difference between the foreground and background colors in Photoshop
    v1.1
    https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-does-photoshop-calculate-lab-values/m-p/15028840
*/

#target photoshop

function calculateDE76(lab1, lab2) {
    var deltaL = lab1[0] - lab2[0];
    var deltaA = lab1[1] - lab2[1];
    var deltaB = lab1[2] - lab2[2];

    return Math.sqrt(deltaL * deltaL + deltaA * deltaA + deltaB * deltaB);
}

function main() {
    /*
    if (!app.documents.length) {
        alert("No document open.");
        return;
    }
    */

    // Get foreground and background colors
    var fgColor = app.foregroundColor.lab;
    var bgColor = app.backgroundColor.lab;

    var fgLab = [Math.round(fgColor.l), Math.round(fgColor.a), Math.round(fgColor.b)];
    var bgLab = [Math.round(bgColor.l), Math.round(bgColor.a), Math.round(bgColor.b)];

    // Calculate dE76
    var dE76 = calculateDE76(fgLab, bgLab);

    alert("Foreground vs. Background Color Picker Difference\n" +
        "Foreground color (L:" + fgLab[0] + " a:" + fgLab[1] + " b:" + fgLab[2] + ")\n" +
        "Background color (L:" + bgLab[0] + " a:" + bgLab[1] + " b:" + bgLab[2] + ")\n" +
        "The dE76 color difference is: " + dE76.toFixed(2));
}

main();

 

 

 

/*
    Calculates the CIE94 (dE94) color difference between the foreground and background colors in Photoshop
    v1.1
    https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-does-photoshop-calculate-lab-values/m-p/15028840
*/


#target photoshop

function calculateCIE94(lab1, lab2) {
    // Weighting factors for CIE94
    var kL = 1;
    var kC = 1;
    var kH = 1;
    var K1 = 0.045;
    var K2 = 0.015;

    // Differences in Lab
    var deltaL = lab1[0] - lab2[0];
    var deltaA = lab1[1] - lab2[1];
    var deltaB = lab1[2] - lab2[2];

    // Calculate chroma
    var c1 = Math.sqrt(lab1[1] * lab1[1] + lab1[2] * lab1[2]);
    var c2 = Math.sqrt(lab2[1] * lab2[1] + lab2[2] * lab2[2]);
    var deltaC = c1 - c2;

    // Calculate deltaH (corrected)
    var deltaH = deltaA * deltaA + deltaB * deltaB - deltaC * deltaC;

    // Scaled components
    var sl = 1; // Lightness scale
    var sc = 1 + K1 * c1; // Chroma scale
    var sh = 1 + K2 * c1; // Hue scale

    // CIE94 formula
    var dE94 = Math.sqrt(
        Math.pow(deltaL / (kL * sl), 2) +
        Math.pow(deltaC / (kC * sc), 2) +
        Math.pow(deltaH / (kH * sh), 2)
    );

    return dE94;
}

function main() {

    /*
    if (!app.documents.length) {
        alert("No document open.");
        return;
    }
    */

    // Get foreground and background colors
    var fgColor = app.foregroundColor.lab;
    var bgColor = app.backgroundColor.lab;

    var fgLab = [Math.round(fgColor.l), Math.round(fgColor.a), Math.round(fgColor.b)];
    var bgLab = [Math.round(bgColor.l), Math.round(bgColor.a), Math.round(bgColor.b)];

    // Calculate dE94
    var dE94 = calculateCIE94(fgLab, bgLab);

    alert("Foreground vs. Background Color Picker Difference\n" +
        "Foreground color (L:" + fgLab[0] + " a:" + fgLab[1] + " b:" + fgLab[2] + ")\n" +
        "Background color (L:" + bgLab[0] + " a:" + bgLab[1] + " b:" + bgLab[2] + ")\n" +
        "The CIE94 color difference is: " + dE94.toFixed(2));
}

main();

 

 

 

/*
    Calculates the CIEDE2000 (dE00) color difference between the foreground and background colors in Photoshop
    v1.1
    https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-does-photoshop-calculate-lab-values/m-p/15028840
*/

#target photoshop

function calculateCIEDE2000(lab1, lab2) {
    // Weighting factors
    var kL = 1;
    var kC = 1;
    var kH = 1;

    // Helper functions
    function degToRad(deg) {
        return (deg * Math.PI) / 180;
    }
    function radToDeg(rad) {
        return (rad * 180) / Math.PI;
    }

    // Calculate chroma
    var c1 = Math.sqrt(lab1[1] * lab1[1] + lab1[2] * lab1[2]);
    var c2 = Math.sqrt(lab2[1] * lab2[1] + lab2[2] * lab2[2]);

    // Mean chroma
    var cBar = (c1 + c2) / 2;

    // Calculate G
    var g = 0.5 * (1 - Math.sqrt(Math.pow(cBar, 7) / (Math.pow(cBar, 7) + Math.pow(25, 7))));

    // Adjusted a values
    var a1Prime = lab1[1] * (1 + g);
    var a2Prime = lab2[1] * (1 + g);

    // Recalculate chroma with adjusted a values
    var c1Prime = Math.sqrt(a1Prime * a1Prime + lab1[2] * lab1[2]);
    var c2Prime = Math.sqrt(a2Prime * a2Prime + lab2[2] * lab2[2]);

    // Mean chroma prime
    var cBarPrime = (c1Prime + c2Prime) / 2;

    // Calculate h primes
    var h1Prime = Math.atan2(lab1[2], a1Prime);
    var h2Prime = Math.atan2(lab2[2], a2Prime);

    if (h1Prime < 0) h1Prime += 2 * Math.PI;
    if (h2Prime < 0) h2Prime += 2 * Math.PI;

    var hBarPrime = Math.abs(h1Prime - h2Prime) > Math.PI
        ? (h1Prime + h2Prime + 2 * Math.PI) / 2
        : (h1Prime + h2Prime) / 2;

    // Delta h prime
    var deltaHPrimeRaw = Math.abs(h1Prime - h2Prime) > Math.PI
        ? h2Prime - h1Prime + 2 * Math.PI * (h2Prime <= h1Prime ? 1 : -1)
        : h2Prime - h1Prime;

    // Delta L, C, and H primes
    var deltaLPrime = lab2[0] - lab1[0];
    var deltaCPrime = c2Prime - c1Prime;
    var deltaHPrime = 2 * Math.sqrt(c1Prime * c2Prime) * Math.sin(deltaHPrimeRaw / 2);

    // Weighting functions
    var lBar = (lab1[0] + lab2[0]) / 2;
    var t = 1
        - 0.17 * Math.cos(hBarPrime - degToRad(30))
        + 0.24 * Math.cos(2 * hBarPrime)
        + 0.32 * Math.cos(3 * hBarPrime + degToRad(6))
        - 0.20 * Math.cos(4 * hBarPrime - degToRad(63));

    var sl = 1 + ((0.015 * Math.pow(lBar - 50, 2)) / Math.sqrt(20 + Math.pow(lBar - 50, 2)));
    var sc = 1 + 0.045 * cBarPrime;
    var sh = 1 + 0.015 * cBarPrime * t;
    var deltaTheta = degToRad(30) * Math.exp(-Math.pow((hBarPrime - degToRad(275)) / degToRad(25), 2));
    var rc = 2 * Math.sqrt(Math.pow(cBarPrime, 7) / (Math.pow(cBarPrime, 7) + Math.pow(25, 7)));
    var rt = -rc * Math.sin(2 * deltaTheta);

    // CIEDE2000 formula
    var dE00 = Math.sqrt(
        Math.pow(deltaLPrime / (kL * sl), 2) +
        Math.pow(deltaCPrime / (kC * sc), 2) +
        Math.pow(deltaHPrime / (kH * sh), 2) +
        rt * (deltaCPrime / (kC * sc)) * (deltaHPrime / (kH * sh))
    );

    return dE00;
}

function main() {

    /*
    if (!app.documents.length) {
        alert("No document open.");
        return;
    }
    */

    // Get foreground and background colors
    var fgColor = app.foregroundColor.lab;
    var bgColor = app.backgroundColor.lab;

    var fgLab = [Math.round(fgColor.l), Math.round(fgColor.a), Math.round(fgColor.b)];
    var bgLab = [Math.round(bgColor.l), Math.round(bgColor.a), Math.round(bgColor.b)];

    // Calculate dE00
    var dE00 = calculateCIEDE2000(fgLab, bgLab);

    alert("Foreground vs. Background Color Picker Difference\n" +
        "Foreground color (L:" + fgLab[0] + " a:" + fgLab[1] + " b:" + fgLab[2] + ")\n" +
        "Background color (L:" + bgLab[0] + " a:" + bgLab[1] + " b:" + bgLab[2] + ")\n" +
        "The CIEDE2000 color difference is: " + dE00.toFixed(2));
}

main();

 

 

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html