node.jscolor-thief

Node.js: Why does pure black (#000000) get detected as RGB 4, 4, 4?


I have used node-vibrant, get-image-colors, colorthief, all of them detect #000000 as RGB 4, 4, 4.
Image here. Just took a picture of an empty portion of the Command Prompt.

The code I've provided below finds this as 4, 4, 4 (currently using node-vibrant, but every other package also does the same.)

const fs = require('fs')
const gm = require('gm')
var Vibrant = require('node-vibrant')
Vibrant.from('test3.png').getPalette()
  .then((palette) => console.log(palette))

The output of this code is:

Swatch {
  _rgb: [ 4, 4, 4 ],
  _population: 180,
  _hsl: [ 0, 0, 0.01568627450980392 ]
}

How do I fix this? Thank you for taking the time to see this question. Also, I am fine if you provide code that involves ColorThief or get-image-colors.


Solution

  • I used get-pixels (what get-image-colors uses itself) and counted the values, it ends up with an object with the amount of times each color appears, and max is the value that appears most..

    this results with: {"#000000ff":4641,"max":"#000000ff"} for your file..

    this code isn't very generic, but you can adapt it to do whatever you need..

    getPixels('./assets/black.png', (err, pixels) => {
        const data = pixels.data;
        let mapped = {};
        let max = undefined;
        let keys = Object.keys(pixels.data);
        for(let i=0; i < keys.length;i+=4){
            let key = "#"+data[keys[i]].toString(16).padStart(2, "0")+
                          data[keys[i+1]].toString(16).padStart(2, "0")+
                          data[keys[i+2]].toString(16).padStart(2, "0")+
                          data[keys[i+3]].toString(16).padStart(2, "0");
    
            if(mapped[key]){
                mapped[key] += 1;
            } else {
                 mapped[key] = 1 ;
            }
            if(max == undefined || mapped[key] > mapped[max]){
                max = key;
            }
        }
        mapped["max"] = max;
    }