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

相关推荐
夏天想2 分钟前
vue通过iframe引入一个外链地址,怎么保证每次切换回这个已经打开的tab页的时候iframe不会重新加载
前端·javascript·vue.js
GISer_Jing3 分钟前
2026年前端开发目标(From豆包)
前端·学习·aigc
CCPC不拿奖不改名5 分钟前
python基础面试编程题汇总+个人练习(入门+结构+函数+面向对象编程)--需要自取
开发语言·人工智能·python·学习·自然语言处理·面试·职场和发展
2501_9444241211 分钟前
Flutter for OpenHarmony游戏集合App实战之数字拼图滑动交换
android·开发语言·flutter·游戏·harmonyos
偷星星的贼1117 分钟前
C++中的访问者模式实战
开发语言·c++·算法
军军君0130 分钟前
Three.js基础功能学习十一:动画与音频
前端·javascript·3d·js·threejs·三维
我即将远走丶或许也能高飞31 分钟前
reduxjs/toolkit 的学习使用
前端·javascript·学习·reactjs
Coder_Boy_31 分钟前
基于SpringAI的在线考试系统-知识点管理模块完整优化方案
java·前端·人工智能·spring boot
莫问前路漫漫36 分钟前
Java Runtime Environment(JRE)全解析:Java 程序跨平台运行的核心基石
java·开发语言
进阶小白猿37 分钟前
Java技术八股学习Day22
java·开发语言·学习