The Color & Illumination Engineering JavaScript Library

The Color & Illumination Engineering toolbox is a JavaScript/TypeScript library for advanced color engineering calculations. You can use it in your Web application, or write typescript or javascript programs using the Deno Typescript runtime. A runtime, in Javascript, is a program that executes the instructions in your script on your computer, which typically runs in a shell.

Here is a quick example, of a JavaScript program d65.js, which prints the chromaticity coordinates for a standard daylight D65, using the CIE1931 color matching functions:


    // import library and objects, and intialise
    import init, { D65, White, Observer, fetchCIE1931_5nm } 
        from "https://www.gerardharbers.com/cie.js";
    await init();

    const d65 = new D65;
    const white = new White;
    const cie1931 = await fetchCIE1931_5nm();

    const stdObs31 = new Observer(cie1931, d65);
    const [,x,y] = stdObs31.lxy(white); 

    console.log(x.toFixed(5),y.toFixed(5));
    // Expect: "0.32172, 0.32903" per CIE.15.2004 Table T3

For a detailed explanation of the code see the Color & Illumination Toolbox book. Here is how the script is run (the --allow-net option is required as the script uses fetch to download data files from the server), and the output as shown on my computer:


    % deno run --allow-net d65.js
    0.31272 0.32903

The library is somewhat different from other —more conventional— color libraries as it uses spectral power distributions as the basis for color calculations exclusively. If you have, for example, a color specification such as a set of red, green, and blue values for a pixel on display, the library will generate a spectral power distribution of the pixel emission based on the spectral primaries of the display used. If you know the spectral power distribution of your display primaries, you can use those, but if you don’t, the library provides many generic spectral power distributions too.

Using spectral data instead of only color coordinates means better accuracy when managing color. You might agree intuitively, as how can you model, for example, the interaction of a complex spectral distribution from a fluorescent lamp with the reflection of your skin by just reducing both to only three numbers? Traditional colorimetry also uses a single average observer, whose color profile was established in the early 1900s, based on only a few measurements from a relatively few observers. We know now, that we don’t see all the same colors. That is pretty obvious for observers with a color vision deficiency but is also true for “normal” observers, but it is known that color perception can be influenced by health, and by age. Using spectral distributions to specify color and light allows us to optimize color fidelity targeted for groups of observers, or even individual observers.

If this sounds complicated, it kind of is, but in practice, you won’t have to deal with much of the data, as the library does all the work for you. And if you wonder if all this does not slow calculations down, you might be surprised: almost all code, running behind the scenes, is written in the programming language Rust and compiled to WebAssembly code. This means that it is pretty fast, and runs on many platforms without complicated installation procedures! You either run it in a (modern) Web browser, which you probably already have installed when you want to run it in a Web app, or install Deno, which is pretty straightforward when you are more interested in using it with command line scripts.

If you are still interested to learn more, or maybe even start using the library yourself: here are some links for more information.