Get the average color of the image using Javascript

Not sure if this is possible, but you need to write a script that will return the average hex or rgb value for the image. I know this can be done in AS, but you want to do it in JavaScript.

+103
javascript image-manipulation
Mar 29 '10 at 21:42
source share
12 answers

AFAIK, the only way to do this is with <canvas/> ...

DEMO V2 : http://jsfiddle.net/xLF38/818/

Please note that this will only work with images in the same domain and in browsers that support HTML5 canvas:

 function getAverageRGB(imgEl) { var blockSize = 5, // only visit every 5 pixels defaultRGB = {r:0,g:0,b:0}, // for non-supporting envs canvas = document.createElement('canvas'), context = canvas.getContext && canvas.getContext('2d'), data, width, height, i = -4, length, rgb = {r:0,g:0,b:0}, count = 0; if (!context) { return defaultRGB; } height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height; width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width; context.drawImage(imgEl, 0, 0); try { data = context.getImageData(0, 0, width, height); } catch(e) { /* security error, img on diff domain */ return defaultRGB; } length = data.data.length; while ( (i += blockSize * 4) < length ) { ++count; rgb.r += data.data[i]; rgb.g += data.data[i+1]; rgb.b += data.data[i+2]; } // ~~ used to floor values rgb.r = ~~(rgb.r/count); rgb.g = ~~(rgb.g/count); rgb.b = ~~(rgb.b/count); return rgb; } 

For IE, check out excanvas .

+126
Mar 29 '10 at 22:30
source share

I realized that I would publish a project that I recently ran into to get the dominant color:

Color thief

A script to capture the dominant color or representative color palette from an image. Uses javascript and canvas.

Other solutions that mention and suggest dominant color never answer a question in the proper context ("in javascript"). I hope this project will help those who want to do just that.

+77
Dec 07 2018-11-11T00: 00Z
source share

The "dominant color" is complex. What you want to do is compare the distance between each pixel and each other pixel in the color space (Euclidean Distance), and then find the pixel whose color is closest to any other color. This pixel is the dominant color. Medium color will usually be dirt.

I wish I had MathML to show you the Euclidean distance. Google it.

I performed the above execution in RGB color space using PHP / GD here: https://gist.github.com/cf23f8bddb307ad4abd8

It is, however, very expensive. This will crash your system on large images and, of course, crash your browser if you try it on the client. I worked on the reorganization of my execution: - save the results in the search table for future use in iteration for each pixel. - Divide large images into 20px 20px grids for localized dominance. - use the Euclidean distance between x1y1 and x1y2 to find out the distance between x1y1 and x1y3.

Please let me know if you make progress on this front. I would be glad to see that. I will do the same.

Canvas is by far the best way to do this in the client. SVG no, SVG - vector. After I take off the performance, the next thing I want to do is run it on the canvas (perhaps with a webmaster to calculate the total distance on each pixel).

Another thing to think about is that RGB is not a good color space for this, because the Euclidean distance between the colors in the RGB space is not very close to the visual distance. The best color space for this may be LUV, but I did not find a good library or any algorithms for converting RGB to LUV for this.

A completely different approach would be to sort your colors in a rainbow and build a histogram with tolerance to account for different shades of color. I have not tried this because sorting colors in a rainbow is difficult, and so are color histograms. I could try this further. Again, let me know if you are making any progress here.

+47
Mar 30
source share

First: this can be done without an HTML5 or SVG canvas.
In fact, someone just managed to generate client-side PNG files using JavaScript , without canvas or SVG, using a data URI scheme .

Secondly: in fact, you may not need Canvas, SVG, or any of the above. If you need to process images only on the client side, without changing them, all this is not required.

You can get the source address from the img tag on the page, make an XHR request - it will most likely come from the browser cache - and treat it like a stream of bytes from Javascript.
You need a good understanding of the image format. (This generator is based in part on libpng sources and may serve as a good starting point.)

+15
Mar 29 '10 at 23:08
source share

I would say through the HTML canvas tag.

You can find here a post from @Georg talking about the small Opera code:

 // Get the CanvasPixelArray from the given coordinates and dimensions. var imgd = context.getImageData(x, y, width, height); var pix = imgd.data; // Loop over each pixel and invert the color. for (var i = 0, n = pix.length; i < n; i += 4) { pix[i ] = 255 - pix[i ]; // red pix[i+1] = 255 - pix[i+1]; // green pix[i+2] = 255 - pix[i+2]; // blue // i+3 is alpha (the fourth element) } // Draw the ImageData at the given (x,y) coordinates. context.putImageData(imgd, x, y); 

This inverts the image using the R, G, and B values โ€‹โ€‹of each pixel. You can easily save RGB values, then round red, green, and blue arrays and finally convert them back to HEX code.

+9
Mar 29
source share

I recently came across a jQuery plugin that does what I originally wanted https://github.com/briangonzalez/jquery.adaptive-backgrounds.js in regards to getting the dominant color from the image.

+5
May 18 '16 at 14:14
source share

Javascript does not have access to images of individual pixel colors. At least not until html5 ... at this point it makes sense that you can draw the image on the canvas and then inspect the canvas (maybe I never did this myself).

+4
Mar 29 '10 at 21:48
source share

This is a โ€œcolor quantizationโ€ that has several approaches, such as MMCQ (Modified Medium Slicer Quantization) or OQ (Octree Quantization). A different approach uses K-Means to produce clusters of colors.

I put it all together since I found a solution for tvOS where there is a subset of XHTML that does not have a <canvas/> :

Create dominant colors for an RGB image with XMLHttpRequest

+1
Oct 26 '15 at 14:30
source share

All-in-One Solution

I would personally combine Color Thief with this modified version of Name that Color to get a more than enough array of dominant color results for images.

Example:

Consider the following image:

enter image description here

You can use the following code to extract dominant color image data:

 let color_thief = new ColorThief(); let sample_image = new Image(); sample_image.onload = () => { let result = ntc.name('#' + color_thief.getColor(sample_image).map(x => { const hex = x.toString(16); return hex.length === 1 ? '0' + hex : hex; }).join('')); console.log(result[0]); // #f0c420 : Dominant HEX/RGB value of closest match console.log(result[1]); // Moon Yellow : Dominant specific color name of closest match console.log(result[2]); // #ffff00 : Dominant HEX/RGB value of shade of closest match console.log(result[3]); // Yellow : Dominant color name of shade of closest match console.log(result[4]); // false : True if exact color match }; sample_image.crossOrigin = 'anonymous'; sample_image.src = document.getElementById('sample-image').src; 
+1
May 3 '18 at 4:27
source share

There is an online tool, pickimagecolor.com , to help you find the average or dominant color of an image. You just need to download the image from your computer, and then click on the image. It gives medium color in HEX, RGB and HSV. He also finds color shades matching that color. I have used it several times.

0
Oct 02 '17 at 10:49 on
source share

A less accurate but fastest way to get the average color of an image with datauri support:

 function get_average_rgb(img) { var context = document.createElement('canvas').getContext('2d'); if (typeof img == 'string') { var src = img; img = new Image; img.setAttribute('crossOrigin', ''); img.src = src; } context.imageSmoothingEnabled = true; context.drawImage(img, 0, 0, 1, 1); return context.getImageData(1, 1, 1, 1).data.slice(0,3); } 
0
Apr 14 '18 at 23:36
source share

As stated in other answers, often what you really need is the dominant color, as opposed to the middle color, which is usually brown. I wrote a script that gets the most common color and placed it on this list.

0
Jun 26 '19 at 20:42 on
source share



All Articles