Grab the Dominant Color Of Image With JavaScript
November 11, 2017 by Andreas Wik
For a profile page template I was designing recently I needed a way to pick a color that would work well together with the user’s profile photo. Now, this can obviously not be done manually as users will upload their profile photo themselves, so this color needs to be generated dynamically.
Luckily, Mr Lokesh Dhakar has built a neat little JavaScript library called Color Thief, which simply gives you the dominant color of your chosen image, or, if you need more than one, a palette of colors.
Now, let’s play!
Go grab a copy of Color Thief and include them on your page. Also add your image.
Next, let’s create the colorThief object and grab the dominant color of the image.
const colorThief = new ColorThief();
const img = document.querySelector('img');
img.addEventListener('click', function() {
const color = colorThief.getColor(this);
// Console log the dominant color
console.log('Dominant color:' + color);
});
Using external images
If you use an external image (not hosted on your domain), then there’s quite a big risk that you run into the following error:
Uncaught DOMException: Failed to execute ‘getImageData’ on ‘CanvasRenderingContext2D’: The canvas has been tainted by cross-origin data.
at CanvasImage.getImageData
Make sure that the server where the image is hosted provides the necessary Allow-Control-Allow-Origin header to allow you doing this. Or, just use local images if you can and you’ll have one thing less to worry about.
Palette of colors
Color Thief also lets you grab a palette of representative colors of the image. Let’s get a palette of four from our image:
const palette = colorThief.getPalette(this, 5);
// Loop through the array of colors
palette.forEach(el => {
// Console log each color
console.log(el);
})
Final code
Let’s wrap this up. Here is a full demo you can copy and play around with:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Color Thief</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
background: #f7f7ef;
display: flex;
align-items: center;
display: flex;
flex-direction: column;
height: 100%;
gap: 20px;
}
img {
margin-top: 20px;
cursor: pointer;
max-width: 300px;
}
#palette {
display: flex;
flex-direction: row;
gap: 20px;
}
#palette div {
width: 45px;
height: 45px;
border-radius: 50%;
}
#dominant div {
width: 70px;
height: 70px;
border-radius: 50%;
}
#color {
width: 70px;
height: 70px;
border-radius: 50%;
}
</style>
</head>
<body>
<img src="shoes.jpg">
<div id="palette"></div>
<div id="color"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.umd.js"></script>
<script>
const colorThief = new ColorThief();
const img = document.querySelector('img');
img.addEventListener('click', function() {
const color = colorThief.getColor(this);
document.getElementById('color').style.backgroundColor = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
const palette = colorThief.getPalette(this, 5);
palette.forEach(el => {
const div = document.createElement('div');
div.style.backgroundColor = `rgb(${el[0]}, ${el[1]}, ${el[2]})`;
document.getElementById('palette').appendChild(div);
})
});
</script>
</body>
</html>
Happy coding!