javascriptcolor-thief

How to change this javascript code to show a modified image?


I am playing with image color quantization algorithms. I have found this link

Color Thief

where a javascript (a language that I have never studied) implementation of a modified median cut algorithm is presented. But the demo shows just the ten dominant colors.

I would like to see what the quantized image looks like. In the file src/color-thief.js (line 132), there is a call to the quantization function. This functions returns a CMap object, which can be used to extract the dominant colors and to map a color to the best one in the reduced color palette. Given the CMap object, how do I modify the original image and show it?

Edit 1

This question is not about color quantization algorithms, but what i need to change in the Color Thief project in order to show a modified image. Suppose that, when i click the 'Click' button, i want to show the image after adding to all its pixels the value 10.


Solution

  • Here, I made this just for you.

    I assume you want to simplify colors of an image to its palette provided by color-thief.

    To achieve this I used color-thief and nearest-color.

    Basically, you want to generate a color-thief's palette, then loop each pixel and get a closest palette value compared to the color of this pixel.

    Check out this solution on codepen, code below:

    /* rgbToHex() and leadingZero() functions ripped from nearest-color. */
    function rgbToHex(rgb) {
      return '#' + leadingZero(rgb.r.toString(16)) +
         leadingZero(rgb.g.toString(16)) + leadingZero(rgb.b.toString(16));
    }
    
    function leadingZero(value) {
      if (value.length === 1) value = '0' + value;   
      return value;
    }
    
    /* Initialize an image and the canvas. */
    var img = document.getElementById("img");
    var canvas = document.getElementById("canvas");
    
    /* When the image is loaded */
    img.onload = function(){
    
      /* Initialize color-thief and get a palette from image. */
      var colorthief = new ColorThief(); 
      var colorthief_palette = colorthief.getPalette(img, 8);
      var palette = {};
    
      /* Turn color-thief palette to nearest-color-compatible palette. */
      for(var i = 0; i < colorthief_palette.length; i++){
        var r = colorthief_palette[i][0];
        var g = colorthief_palette[i][1]; 
        var b = colorthief_palette[i][2];
        var o = {r: r, g: g, b: b};
        palette["color_" + i] = rgbToHex(o);
      }
    
      /* Initialize nearest-color */
      var clr = nearestColor.from(palette);
    
      /* Initialize canvas, draw the image data and hide the default image. */
      var ctx = canvas.getContext("2d");
      canvas.width = img.width;
      canvas.height = img.height;  
      ctx.drawImage(img, 0, 0);
      img.style.display = "none"; 
    
      var data = ctx.getImageData(0, 0, canvas.width, canvas.height);
      var pixel = data.data;
    
      /* Loop for each pixel of image. */
      for (var i = 0, n = pixel.length; i < n; i += 4) {
    
          var r = pixel[i+0];
          var g = pixel[i+1]; 
          var b = pixel[i+2];
          var o = {r: r, g: g, b: b};
          var color = rgbToHex(o);
          var nearest = clr(color);
    
          pixel[i+0] = nearest.rgb.r;
          pixel[i+1] = nearest.rgb.g;
          pixel[i+2] = nearest.rgb.b;
    
    
      } 
    
      ctx.putImageData(data, 0, 0);
    
    }
    

    In result, this image:

    enter image description here

    Becomes this image: enter image description here