I compiled all the pixel data, excluding colors with an alpha value of 0, into a histogram and selected the most popular color. This chosen color was then inverted and applied as the background for the image wrapper.
To work around the CORS policy restrictions affecting ctx.getImageData
, I needed to convert the Imgur image URLs to Base64 in order to manipulate the canvas data. It's worth noting that selecting the most popular color may not always yield optimal results, as some colors are very close and only differ by a few bits. Using methods like average calculation or thresholding might be more effective for grouping similar colors in the histogram.
Note: While my approach is straightforward, there are specialized libraries such as Vibrant.js and Color Thief that are specifically designed to extract color palette information from images.
const ctx = document.querySelector('#hidden-canvas').getContext('2d');
// Helper functions for converting and inverting Hex values
const toHex = (...components) =>
`#${components.map(v => v.toString(16).padStart(2, '0')).join('')}`;
const invertHex = (hex) => {
if (hex.startsWith('#')) hex = hex.slice(1);
const
r = (255 - parseInt(hex.slice(0, 2), 16)).toString(16),
g = (255 - parseInt(hex.slice(2, 4), 16)).toString(16),
b = (255 - parseInt(hex.slice(4, 6), 16)).toString(16);
return toHex(r, g, b);
}
// Function to extract pixels from an image
const extractPixels = (img, ignoreAlpha = true) => {
...
body {
background: #222;
}
.dynamic-image-background {
padding: 1em;
}
#hidden-canvas {
display: none;
}
<script src="https://cdn.rawgit.com/jariz/vibrant.js/master/dist/Vibrant.js"></script>
<div class="dynamic-image-background">
...
</canvas>