利用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获取更多知识

相关推荐
发现一只大呆瓜5 分钟前
React-路由监听 / 跳转 / 守卫全攻略(附实战代码)
前端·react.js·面试
2401_8318249612 分钟前
代码性能剖析工具
开发语言·c++·算法
是wzoi的一名用户啊~25 分钟前
【C++小游戏】2048
开发语言·c++
swipe1 小时前
为什么 RAG 一定离不开向量检索:从文档向量化到语义搜索的工程实现
前端·llm·agent
Sunshine for you1 小时前
C++中的职责链模式实战
开发语言·c++·算法
@我漫长的孤独流浪1 小时前
Python编程核心知识点速览
开发语言·数据库·python
OpenTiny社区1 小时前
AI-Extension:让 AI 真的「看得到、动得了」你的浏览器
前端·ai编程·mcp
IT_陈寒1 小时前
Redis缓存击穿:3个鲜为人知的防御策略,90%开发者都忽略了!
前端·人工智能·后端
qq_416018721 小时前
C++中的状态模式
开发语言·c++·算法
2401_884563241 小时前
模板代码生成工具
开发语言·c++·算法