The color website

ColorfulImg

Welcome to Star ~

ColorfulImg

Colorfulimg is a JS tool library that can get image theme colors from canvas.

Installation:

npm i colorfulimg

Usage:

let colorfulimg = require('colorfulimg') 
let myImg = document.getElementById('myImg')
let rgb = colorfulImg(myImg);
Copy the code

This is the project address

Welcome to star ~

ColorfulImg implementation idea

Here is the implementation idea, mainly through the canvas getImageData() method to get each pixel of the image RGBA data. By obtaining the average method to calculate the picture theme color. So there are two limitations to this effect:

  • Site and image must be the same domain name (getImageData() limits images must be homologous)
  • Browsers must support Canvas

Draw an IMG image on the canvas

  1. First we need to create a new Canvas tag and access its painting context:
let canvas = document.createElement('canvas')
let context = canvas.getContext && canvas.getContext('2d')
Copy the code
  1. Draw an IMG image with the X and Y axes starting at 0:
let myImg = document.getElementById('myImg')
context.drawImage(myImg , 0, 0)
Copy the code

GetImageData ()

The getImageData() API takes four parameters, the first two are the starting point for retrieving the image data, and the last two are the width and height of the rectangle. We need to get all the image data, so the last two parameters are the width and height of the image. At the same time, we also need to set the width and height of the canvas to the width and high energy of the picture to hold the picture completely.

let height = canvas.height = imgEl.height
let width = canvas.width = imgEl.width
let data = context.getImageData(0, 0, width, height).data
Copy the code

I encountered a cross-domain problem in my first test:

Images from different sources must have the attribute crossorigin=”anonymous”, and the server storage side must have the corresponding permissions.

Process the obtained color data

Let’s log what the data is:

It’s an array with a bunch of data, what is the data? Let’s first look at MDN:

That is, if you look at the order in which the first four bits make up an RGBA sequence: RGBA (red, green, Blue, alpha)

For the image data transparency (alpha) is 255, that is, opaque so we do not deal with the transparency, then we just need to sum the other three RGB values and take the mean to get the theme color of the image!

let count = 0
let i = 0
let blockSize = 1
while ( (i += blockSize * 4) < length ) {
  ++count
  rgb.r = data[i] + rgb.r 
  rgb.g = data[i+1] + rgb.g
  rgb.b = data[i+2] + rgb.b
}
rgb.r = ~~(rgb.r/count)
rgb.g = ~~(rgb.g/count)
rgb.b = ~~(rgb.b/count)
Copy the code

The final code

function colorfulImg(img){
    let canvas = document.createElement('canvas'),
        context = canvas.getContext && canvas.getContext('2d'),
        height,width,length,data, 
        i = -4,
        blockSize = 5,
        count = 0,
        rgb = {r:0,g:0,b:0}
            
    height = canvas.height = imgEl.height
    width = canvas.width = imgEl.width
    context.drawImage(imgEl, 0, 0);
    data = context.getImageData(0, 0, width, height).data
    length = data.length
    while ( (i += blockSize * 4) < length ) {
    ++count;
    rgb.r += data[i];
    rgb.g += data[i+1];
    rgb.b += data[i+2];
    }
    rgb.r = ~~(rgb.r/count);
    rgb.g = ~~(rgb.g/count);
    rgb.b = ~~(rgb.b/count);
    return rgb;
}
Copy the code