How to get the average or main color from an image with javascript?

后端 未结 5 1469
失恋的感觉
失恋的感觉 2020-12-30 12:41

what i want is to the the HEX or the RGB average value from an image to the another div background this color.

So if i upload an image with a ot of red i get somethi

5条回答
  •  抹茶落季
    2020-12-30 13:31

    First, draw the image on a canvas:

    function draw(img) {
        var canvas = document.createElement("canvas");
        var c = canvas.getContext('2d');
        c.width = canvas.width = img.width;
        c.height = canvas.height = img.height;
        c.clearRect(0, 0, c.width, c.height);
        c.drawImage(img, 0, 0, img.width , img.height);
        return c; // returns the context
    }
    

    You can now iterate over the image's pixels. A naive approach for color-detection is to simply count the frequency of each color in the image.

    // returns a map counting the frequency of each color
    // in the image on the canvas
    function getColors(c) {
        var col, colors = {};
        var pixels, r, g, b, a;
        r = g = b = a = 0;
        pixels = c.getImageData(0, 0, c.width, c.height);
        for (var i = 0, data = pixels.data; i < data.length; i += 4) {
            r = data[i];
            g = data[i + 1];
            b = data[i + 2];
            a = data[i + 3]; // alpha
            // skip pixels >50% transparent
            if (a < (255 / 2))
                continue; 
            col = rgbToHex(r, g, b);
            if (!colors[col])
                colors[col] = 0;
            colors[col]++;
        }
        return colors;
    }
    
    function rgbToHex(r, g, b) {
        if (r > 255 || g > 255 || b > 255)
            throw "Invalid color component";
        return ((r << 16) | (g << 8) | b).toString(16);
    }
    

    getColors returns a map of color names and counts. Transparent pixels are skipped. It should be trivial to get the most-frequently seen color from this map.

    If you literally want an average of each color component, you could easily get that from the results of getColors, too, but the results aren't likely to be very useful. This answer explains a much better approach.

    You can use it all like this:

    // nicely formats hex values
    function pad(hex) {
        return ("000000" + hex).slice(-6);
    }
    
    // see this example working in the fiddle below
    var info = document.getElementById("info");
    var img = document.getElementById("squares");
    var colors = getColors(draw(img));
    for (var hex in colors) {
        info.innerHTML += "
  • " + pad(hex) + "->" + colors[hex]; }
  • See a working example.

提交回复
热议问题