在 Windows 的设置里有个主题色,可以根据壁纸的颜色,设置窗口标题栏和边框、"开始"按钮或任务栏的颜色。在 Twitter 点击图片进入大图模式时,背景颜色会变成当前图片的主色调,切换图片时,背景色也会跟着变换,看起来颇为灵动,遂想动手自己实现一下这个效果。
实现思路
Canvas提供了getImageData()
的方法,能获取到图片每个像素点的rgba数据,利用拿到的数据加以计算,就可以计算出整张图片的主色调了。流程如下:
- 读取图片数据,将其转换为 Canvas 对象
- 在 Canvas 上绘制图片
- 使用 getImageData 方法获取图像数据
- 遍历图像数据中的像素,计算颜色出现次数
- 找到出现次数最多的颜色,即为图片的主色调
把以上流程转化成代码:
const img = new Image();
img.src = 'example.jpg';
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const pixelData = imageData.data;
const colorCounts = {};
let maxCount = 0;
let dominantColor = [0, 0, 0];
for (let i = 0; i < pixelData.length; i += 4) {
const r = pixelData[i];
const g = pixelData[i + 1];
const b = pixelData[i + 2];
const key = `${r}, ${g}, ${b}`;
if (colorCounts[key]) {
colorCounts[key]++;
} else {
colorCounts[key] = 1;
}
if (colorCounts[key] > maxCount) {
maxCount = colorCounts[key];
dominantColor = [r, g, b];
}
}
console.log(`Dominant color: rgb(${dominantColor[0]}, ${dominantColor[1]}, ${dominantColor[2]})`);
};
这种方法只能提取一种主色调,想要获取多种主色调,就要使用类似K-Means算法的颜色聚类方法了。