当我们找到一些图,会发现有白色或其他颜色的背景,如果是纯色背景,那么我们可以利用canvas的技术来一键替换掉背景,从而实现"抠图"效果
一、原始图片

二、开始替换
网站地址:https://huatuya.com
2.1 选择图片

2.2 选择空白背景色点击

2.3 完事之后点击预览进行下载

三、最终效果

四、核心原理
主要是利用canvas技术 将图片四个角的1像素的颜色取出,然后 全局替换这个颜色,最好替换原图片
核心代码:
javascript
const currentImg =reactive({obj:{src:'图片地址'}})
//一键替换背景色
const processImage = () => {
if (!currentImg.obj) return;
setTimeout(() => {
try {
// 获取图片数据
const img = new Image();
img.src = currentImg.obj.src;
const classId = 'koutu' + currentImg.obj.id;
let resultCanvas = document.querySelector('#' + classId);
if (!resultCanvas) {
resultCanvas = document.createElement('canvas');
resultCanvas.setAttribute('id', classId); //添加样式属性
document.body.appendChild(resultCanvas);
}
img.onload = () => {
try {
// 设置Canvas尺寸
// originalCanvas.value.width = img.width;
// originalCanvas.value.height = img.height;
resultCanvas.width = img.width;
resultCanvas.height = img.height;
const resultCtx = resultCanvas.getContext('2d');
// 绘制原始图片到结果canvas
resultCtx.drawImage(img, 0, 0);
// 获取像素数据
const imageData = resultCtx.getImageData(0, 0, img.width, img.height);
const data = imageData.data;
// 获取背景色(取四个角的颜色平均值)
const corners = [
{ x: 0, y: 0 },
{ x: img.width - 1, y: 0 },
{ x: 0, y: img.height - 1 },
{ x: img.width - 1, y: img.height - 1 }
];
let rSum = 0,
gSum = 0,
bSum = 0;
let validCorners = 0;
for (const corner of corners) {
const index = (corner.y * img.width + corner.x) * 4;
// 确保索引在有效范围内
if (index >= 0 && index < data.length) {
rSum += data[index];
gSum += data[index + 1];
bSum += data[index + 2];
validCorners++;
}
}
if (validCorners === 0) {
console.log('无法检测图片背景色');
//isProcessing.value = false;
return;
}
const bgR = Math.round(rSum / validCorners);
const bgG = Math.round(gSum / validCorners);
const bgB = Math.round(bSum / validCorners);
// 替换背景色
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// 计算与背景色的差异
const diff = Math.sqrt(Math.pow(r - bgR, 2) + Math.pow(g - bgG, 2) + Math.pow(b - bgB, 2));
// 如果颜色接近背景色,则替换
if (diff < tolerance.value) {
if (!backgroundColor.value || backgroundColor.value === 'transparent') {
// 设置为透明
data[i + 3] = 0;
} else {
// 设置为指定颜色
const hex = backgroundColor.value;
if (hex.startsWith('#')) {
data[i] = parseInt(hex.substr(1, 2), 16);
data[i + 1] = parseInt(hex.substr(3, 2), 16);
data[i + 2] = parseInt(hex.substr(5, 2), 16);
}
}
}
}
// 将处理后的数据放回canvas
resultCtx.putImageData(imageData, 0, 0);
// 生成结果图片
currentImg.obj.src = resultCanvas.toDataURL('image/png');
document.body.removeChild(document.getElementById(classId));
console.log('替换成功!');
} catch (error) {
console.log(error);
}
};
} catch (error) {
console.log('处理图片时出错: ' + error.message);
}
}, 100);
};
有不理解的可以留言讨论,也可关注订阅号,解锁更多全栈知识!
原文地址:https://daimane.com/articles/691d88a3f67dd004c87f59cc
或者访问学习网站 https://daimane.com获取更多知识
