Downloadable list of Cosmo RGB and Hex Colours

Looking for a list of RGB or Hex colours for the 2020 Cosmo embroidery floss collection? You can download it or copy the Google Sheets version here: Github: 500 colour Cosmo dataset

Over the winter holiday, my girlfriend asked me to help her with the spreadsheet she uses to keep track of her embroidery floss 1 (check out her creations on Instagram). She wanted to be able to see how many of each colour she owned at a glance, and what kind of inventory she had on hand.

I was provided with a helpful diagram:

Layout diagram which includes thread code, a colour box, and types of inventory on hand

After some discussion, we decided on trying to mimic the layout of the 2020 colour card 2, which looks like this:

Full Cosmo colour card

The goal was to make an inventory dashboard with the same layout as the colour card. This all seemed easy enough, until I got to the problem of finding RGB colours for each thread…

There are some lists out there that will give you RGB colours for Cosmo threads, but they’re much harder to find than lists for DMC (which is a more widely-used brand). cs-pattern.com has a good list, but they only have 400 colours as a result of sampling from an older colour card, as you can see their forum post. I later discovered that MacStitch also ships with a list of Cosmo threads, but it’s also slightly out of date and a little tricky to convert to RGB hex codes.

Another, worse option I tried before finding the cs-pattern list was to use a conversion chart to get an equivalent DMC thread for each Cosmo thread 3, which then allowed me to get a RGB colour from a DMC list. This filled in about half of the colours from the 2020 Cosmo colour card, leaving the other half for me to fill in manually.

In the end, none of these options worked and I ended up sampling my own Cosmo to RGB dataset from the 2020 colour card PDF using GIMP. (Download via GitHub: 500 colour Cosmo dataset.)

Along the way, I learned some interesting things, which are described below.

Problem #1: You (usually) can’t mix data sources

I assume that most thread to RGB colour conversion charts are created by sampling an RGB colour from an image of the threads. If you use multiple data sources, it’s hard to ensure the colours are consistent: the lighting could be different between cameras/scanners and the sampling method could be different. Even differences between software might cause the colour of a single thread to vary from one dataset to another.

Here’s an example of what mixed data sources looks like, comparing a section from the full manual sample (left) with the mixed sourcing I had initially used:

Two columns of purple colours going from lightest to darkest in each column

Left: all manually sampled; Right: mix of DMC conversions and manual samples, with labels for data sources

The colours pulled from converting Cosmo to DMC were lighter and pinker than the manual samples, so the mixed source sequence looks mottled instead of showing a smooth gradient.

Sequences where all the colours came from DMC conversion looked a little better, but still came out a little mottled:

Two columns of pink colours going from lightest to darkest in each column

Left: all manually sampled; Right: all DMC conversions

Why does this matter? Fans of Cosmo threads (including the one that lives in my apartment) say that Cosmo threads have nice gradients. Each colour family has a range of options for slight variations in shade and tone, and this allows you to have very fine control over the colours used in your embroidery.

To show the gradients properly in the inventory spreadsheet, I needed a colour dataset that was very precise. If the measurement of each colour varied more than the differences between neighbouring shades, then the gradient effect would be lost. As you can see in the examples above, the gradients look much better (and closer to how they look on the colour card) if you take all the colours from one consistent source.

Variability between data sources is also a challenge for DMC threads, as evidenced by this spreadsheet comparing different DMC colour lists 4:

Screenshot of a spreadsheet with columns of DMC colours from different sources

So, lesson learned — make sure to use the same data source for consistency. And if the source you need doesn’t exist, you’ll have to make it yourself.

Problem #2: What’s a “correct” RGB colour for a real-world object?

Finding an “equivalent” digital colour for a real-world object can be quite challenging. You have to contend with the difference between the additive (emitted) colour of computer screens compared to the subtractive (reflected) colour of dyed objects, monitor calibration, the colour spaces used by software, and other factors.

Archivists deal with some of these problems by using image targets to calibrate their scanning equipment and to assess the colour accuracy of an image. (This journal article has an example on page 5.) To achieve a certain archival standard, you have to ensure the white balance, colour accuracy, and luminance are within acceptable margins of error.

To my knowledge, no-one has scanned a floss colour card to archival standards, and probably won’t any time soon, since the equipment is quite expensive. But I did want to test the perceived colour accuracy of different data sources, so I set up a blind experiment.

I randomly selected 20 threads with manually sampled and DMC conversion colours, and created blind pairs of both colour sources:

Pairs of coloured cells with two colour cells for each thread

Once everything was set up, I had Katrina look at each floss colour and mark down which of the two computer colours was the better match. Interestingly enough, neither data source had any huge advantage over the other in providing a more “accurate” match to the real-world object. She picked 13/20 of the manually-sampled colours as the better match, and 7/20 of the colours from DMC conversion.

I also tried the experiment, and had even more ambivalent results, with a 50:50 split between manual samples and DMC conversion as being the closer match.

One thing we both noticed while doing the test was that the angle of lighting played a huge role in our perceptions of the physical thread. Cosmo thread is, for lack of a better term, shiny. As you can see from the video below, even minor changes in the angle of lighting affect how light the thread appears.

Katrina also noted that people could have different subjective ideas of what makes a good match. One person could prioritize matching the lightness of the physical thread with the computer colour, while another could prioritize matching the hue, even if the lightness was slightly off.

Miscellaneous Final Thoughts

I also did some experiments with mathematical calculations of colour distance, which are pretty dull to write about. However, the math of calculating the difference between colours, weighted to human perception, is kinda neat and you can read about it on the Wikipedia page on colour difference calculations 5.

If you’re curious about how to sample colours using GIMP, this video tutorial on the color picker tool does a great job of showing the basics. A couple additional tips I would share:

  • If you detach the info window, it looks a lot better and you can move it around. I found it particularly useful to keep the info window next to the part of the image I was sampling to make sure the colour looked right compared to the source.

  • By adjusting the “number of columns” option, you can change the palette layout.

  • If you click on the swatches added to a palette, you can name them. E.g. in this case you could put the thread number used by the manufacturer.

  • You can export palettes to several different formats. Unfortunately, the “text file” format doesn’t include the names given to each swatch, so you’ll have to use one of the other formats (e.g. CSS stylesheet) if you want the names as well.

Diagrams of the palette editing and palette export menus in GIMP

Using the palette menus in GIMP

Final thought — I mentioned archival digitization standards earlier in the post. If you’re interested in this kind of thing, I would glance through the document I had linked above, the 2016 Technical Guidelines for Digitizing Cultural Heritage Materials. It’s incredible how much care goes into digitizing archival objects. It’s much more complicated than just having someone take regular scans of old documents!

  1. My understanding is that “floss” consists of six strands of thread bundled together, which you can split apart as desired. Throughout the post I’ll use “thread” and “floss” somewhat interchangeably. 

  2. A colour card is to floss what a paint chip fan deck is to paint. 

  3. I used this chart from the Two Green Zebras shop in Australia and converted it into a spreadsheet using Tabula. I then got the DMC colours from crazyartzone.com

  4. Source: Bura510 on Reddit r/CrossStitch 

  5. If you want to give it a go yourself in Google Sheets, here’s a custom function you can use, based on the redmean formula from that Wikipedia page:

    /**
     * Compare color difference in RBG hex codes
     * @param {string} rgb1 First RGB hex color starting with #
     * @param {string} rgb2 Second RGB hex color starting with #
     * @customfunction
     */
    function DELTAHEX(hex1, hex2) {
    return deltaRGB([
        parseInt(hex1.slice(1,3), 16),
        parseInt(hex1.slice(3,5), 16),
        parseInt(hex1.slice(5,7), 16)
    ],[
        parseInt(hex2.slice(1,3), 16),
        parseInt(hex2.slice(3,5), 16),
        parseInt(hex2.slice(5,7), 16)
    ]);
    }
    
    /**
     * Compare color difference in RGB
     * @param {Array} rgb1 First RGB color in array
     * @param {Array} rgb2 Second RGB color in array
     * source: https://gist.github.com/ryancat/9972419b2a78f329ce3aebb7f1a09152
     * with slight change to redmean formula used to match more precise Wikipedia version
     */
    function deltaRGB (rgb1, rgb2) {
    const [ r1, g1, b1 ] = rgb1,
            [ r2, g2, b2 ] = rgb2,
            drp2 = Math.pow(r1 - r2, 2),
            dgp2 = Math.pow(g1 - g2, 2),
            dbp2 = Math.pow(b1 - b2, 2),
            t = (r1 + r2) / 2;
    
    return Math.sqrt((2 + t/256) * drp2  +  4 * dgp2  +  (2 + (255 - t) / 256) * dbp2);
    }