利用canvas 实现纯色背景替换 可清空纯色背景

当我们找到一些图,会发现有白色或其他颜色的背景,如果是纯色背景,那么我们可以利用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获取更多知识

相关推荐
吴阿福|一人公司11 分钟前
Python 类变量修改的压力测试:高并发场景
开发语言·python
天天进步201518 分钟前
Tunnelto 源码解析 #13:自托管部署:Docker、环境变量、端口规划与单实例限制
开发语言
Csvn18 分钟前
TypeScript:你以为安全的 `JSON.parse` 其实是颗雷 — 运行时类型安全实战
前端·javascript
AI科技星18 分钟前
第三卷:质数王朝志(全卷定稿)
c语言·开发语言·汇编·electron·概率论
触底反弹22 分钟前
从 JS 引擎执行原理理解数据类型:栈内存、堆内存与作用域
javascript·数据结构·面试
橘子星22 分钟前
深入理解线性数据结构:栈、队列与链表
前端·javascript
dadaobusi23 分钟前
Linux内核完成大量内存/调度/时间子系统初始化的关键阶段
java·linux·前端
用户0595401744623 分钟前
Redis 缓存过期不一致踩坑实录:一个 bug 让我排查了 3 小时,最终用 Pytest 自动化堵上漏洞
前端·css
东风破_24 分钟前
AJAX 异步请求:从回调地狱到 async/await,到底解决了什么?
前端
Larcher25 分钟前
JS 数据类型的八重人格与内存真相
前端·javascript