编辑:只有在发布此内容后,我才意识到@350D 的答案完全相同。
令人惊讶的是,这只需 4 行代码即可完成:
const canvas = document.getElementById("canvas"),
preview = document.getElementById("preview"),
ctx = canvas.getContext("2d");
canvas.width = 1;
canvas.height = 1;
preview.width = 400;
preview.height = 400;
function getDominantColor(imageObject) {
//draw the image to one pixel and let the browser find the dominant color
ctx.drawImage(imageObject, 0, 0, 1, 1);
//get pixel color
const i = ctx.getImageData(0, 0, 1, 1).data;
console.log(`rgba(${i[0]},${i[1]},${i[2]},${i[3]})`);
console.log("#" + ((1 << 24) + (i[0] << 16) + (i[1] << 8) + i[2]).toString(16).slice(1));
}
// vvv all of this is to just get the uploaded image vvv
const input = document.getElementById("input");
input.type = "file";
input.accept = "image/*";
input.onchange = event => {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = readerEvent => {
const image = new Image();
image.onload = function() {
//shows preview of uploaded image
preview.getContext("2d").drawImage(
image,
0,
0,
preview.width,
preview.height,
);
getDominantColor(image);
};
image.src = readerEvent.target.result;
};
reader.readAsDataURL(file, "UTF-8");
};
canvas {
width: 200px;
height: 200px;
outline: 1px solid #000000;
}
<canvas id="preview"></canvas>
<canvas id="canvas"></canvas>
<input id="input" type="file" />
工作原理:
创建画布上下文
const context = document.createElement("canvas").getContext("2d");
这会将图像仅绘制到一个画布像素,使浏览器为您找到主色。
context.drawImage(imageObject, 0, 0, 1, 1);
之后,只需获取像素的图像数据:
const i = context.getImageData(0, 0, 1, 1).data;
最后,转换成rgba或HEX:
const rgba = `rgba(${i[0]},${i[1]},${i[2]},${i[3]})`;
const HEX = "#" + ((1 << 24) + (i[0] << 16) + (i[1] << 8) + i[2]).toString(16).slice(1);
这种方法有一个问题,那就是getImageData 有时会抛出错误Unable to get image data from canvas because the canvas has been tainted by cross-origin data.,这就是你需要在演示中上传图片而不是输入 URL 的原因。
此方法也可用于像素化图像,通过增加图像的宽度和高度来绘制图像。
这适用于 chrome,但可能不适用于其他浏览器。