两种方法去除图片背景
方案一交互式“擦除”换背景Web 版适用场景制作证件照、抠图换背景。无需安装任何软件浏览器打开即用。核心玩法上传前景图如人像和背景图用画笔涂抹擦除原背景露出后面的新背景支持调整笔刷大小和下载结果。html!DOCTYPE htmlhtml langzhheadmeta charsetUTF-8title智能擦除换背景工具/titlestyle* { margin: 0; padding: 0; box-sizing: border-box; }body { background: #1e1e2f; color: #fff; font-family: Arial; display: flex; flex-direction: column; align-items: center; padding: 20px; min-height: 100vh; justify-content: center; }.container { background: #2d2d44; padding: 30px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.5); max-width: 900px; width: 100%; }h2 { text-align: center; margin-bottom: 20px; color: #a78bfa; }.upload-row { display: flex; gap: 20px; justify-content: center; flex-wrap: wrap; margin-bottom: 20px; }.upload-box { background: #3b3b58; padding: 10px 20px; border-radius: 10px; cursor: pointer; transition: 0.3s; border: 2px dashed #6b6b8a; }.upload-box:hover { border-color: #a78bfa; background: #44446a; }.canvas-wrapper { position: relative; display: flex; justify-content: center; background: #1a1a2e; border-radius: 16px; padding: 10px; }canvas { display: block; max-width: 100%; height: auto; border-radius: 8px; cursor: crosshair; background: #000; }.controls { display: flex; gap: 15px; flex-wrap: wrap; justify-content: center; align-items: center; margin: 18px 0 10px; }.controls button, .controls input { padding: 8px 18px; border: none; border-radius: 30px; font-weight: bold; cursor: pointer; transition: 0.2s; }.btn-erase { background: #ef4444; color: #fff; }.btn-restore { background: #3b82f6; color: #fff; }.btn-reset { background: #6b7280; color: #fff; }.btn-download { background: #22c55e; color: #fff; }.controls button:hover { transform: scale(1.05); opacity: 0.9; }.info { color: #9ca3af; font-size: 14px; margin-top: 10px; text-align: center; }/style/headbodydiv classcontainerh2️ 擦除前景 · 露出新背景/h2div classupload-rowlabel classupload-box 上传前景 (要擦除的) input typefile idfgInput acceptimage/* hidden/labellabel classupload-box 上传新背景 input typefile idbgInput acceptimage/* hidden/label/divdiv classcanvas-wrappercanvas idcanvas width700 height500/canvas/divdiv classcontrolsspan️ 笔刷大小: input typerange idbrushSize min5 max80 value30/spanbutton classbtn-erase idmodeErase 擦除模式/buttonbutton classbtn-restore idmodeRestore✨ 恢复模式/buttonbutton classbtn-reset idresetBtn 重置/buttonbutton classbtn-download iddownloadBtn⬇️ 下载合成图/button/divdiv classinfo 提示擦除模式下涂抹为透明露出背景恢复模式下可涂回原图。/div/divscriptconst canvas document.getElementById(canvas);const ctx canvas.getContext(2d);let isDrawing false;let mode erase; // erase or restorelet fgImage null;let bgImage null;let isFgLoaded false;let isBgLoaded false;// 加载前景document.getElementById(fgInput).onchange (e) {const file e.target.files[0];if (!file) return;const img new Image();img.onload () { fgImage img; isFgLoaded true; drawScene(); };img.src URL.createObjectURL(file);};// 加载背景document.getElementById(bgInput).onchange (e) {const file e.target.files[0];if (!file) return;const img new Image();img.onload () { bgImage img; isBgLoaded true; drawScene(); };img.src URL.createObjectURL(file);};function drawScene() {// 先画背景如果存在if (isBgLoaded bgImage) {ctx.drawImage(bgImage, 0, 0, canvas.width, canvas.height);} else {ctx.fillStyle #2a2a3a;ctx.fillRect(0, 0, canvas.width, canvas.height);}// 再画前景如果存在if (isFgLoaded fgImage) {ctx.drawImage(fgImage, 0, 0, canvas.width, canvas.height);}}// --- 鼠标绘图逻辑 ---function getPos(e) {const rect canvas.getBoundingClientRect();const scaleX canvas.width / rect.width;const scaleY canvas.height / rect.height;const clientX e.touches ? e.touches[0].clientX : e.clientX;const clientY e.touches ? e.touches[0].clientY : e.clientY;return { x: (clientX - rect.left) * scaleX, y: (clientY - rect.top) * scaleY };}function drawDot(x, y) {const radius parseInt(document.getElementById(brushSize).value);ctx.globalCompositeOperation (mode erase) ? destination-out : source-over;if (mode restore fgImage) {// 恢复模式从原图取像素覆盖但为了简单我们用 destination-out 擦掉透明再画原图// 更好的方法直接用 source-over 画一个不透明的圆形但颜色取原图太复杂。改为恢复到原始前景图。// 这里简化在恢复模式下我们使用 source-over 画上原图的一部分裁剪复制// 更优雅保存原始前景的 ImageData恢复时直接 putImageData。// 由于我们之前没有保存简单起见点击恢复模式时我们直接用原图覆盖整个画布那样会把背景也盖掉。// 为了完美恢复我们存储原始前景的副本。}// 标准擦除 (destination-out)if (mode erase) {ctx.beginPath();ctx.arc(x, y, radius, 0, Math.PI * 2);ctx.fill();} else {// 恢复模式由于无法直接从下层背景取色我们使用临时方案重新绘制全局但只恢复局部// 更稳健的方法保存一份原始前景绘制在内存画布上。// 实现一个内存画布保存原始前景。}// 由于上面逻辑复杂我们采用全局策略在内存中保存原始前景恢复时从内存画布取像素覆盖。// 下面重新完善实现见下方完整升级版这里为了代码不断裂保留基础逻辑。}// 为了更佳体验提供一个简单但有效的升级保存原始前景图片数据。let originalFgData null;const tempCanvas document.createElement(canvas);tempCanvas.width canvas.width;tempCanvas.height canvas.height;const tempCtx tempCanvas.getContext(2d);// 重写 drawScene 以保存数据const originalDrawScene drawScene;drawScene function() {if (isBgLoaded bgImage) {ctx.drawImage(bgImage, 0, 0, canvas.width, canvas.height);} else {ctx.fillStyle #2a2a3a;ctx.fillRect(0, 0, canvas.width, canvas.height);}if (isFgLoaded fgImage) {ctx.drawImage(fgImage, 0, 0, canvas.width, canvas.height);// 保存原始前景到临时画布用于恢复tempCtx.clearRect(0, 0, canvas.width, canvas.height);tempCtx.drawImage(fgImage, 0, 0, canvas.width, canvas.height);originalFgData tempCtx.getImageData(0, 0, canvas.width, canvas.height);}};// 重写绘图事件function drawAt(x, y) {const radius parseInt(document.getElementById(brushSize).value);if (mode erase) {ctx.globalCompositeOperation destination-out;ctx.beginPath();ctx.arc(x, y, radius, 0, Math.PI * 2);ctx.fill();} else {// 恢复模式从 originalFgData 取像素贴回去if (!originalFgData) return;ctx.globalCompositeOperation source-over;// 为了性能只恢复一个圆形区域const imageData ctx.getImageData(x-radius, y-radius, radius*2, radius*2);const data imageData.data;const origData originalFgData.data;const w canvas.width;for (let dy -radius; dy radius; dy) {for (let dx -radius; dx radius; dx) {if (dx*dx dy*dy radius*radius) continue;const px Math.round(x dx);const py Math.round(y dy);if (px 0 || py 0 || px canvas.width || py canvas.height) continue;const idx (py * w px) * 4;const origIdx idx; // 因为原图尺寸一致data[idx] origData[origIdx];data[idx1] origData[origIdx1];data[idx2] origData[origIdx2];data[idx3] origData[origIdx3];}}ctx.putImageData(imageData, x-radius, y-radius);}}// 鼠标/触摸事件canvas.addEventListener(mousedown, (e) { isDrawing true; const p getPos(e); drawAt(p.x, p.y); });canvas.addEventListener(mousemove, (e) { if (!isDrawing) return; const p getPos(e); drawAt(p.x, p.y); });canvas.addEventListener(mouseup, () { isDrawing false; });canvas.addEventListener(mouseleave, () { isDrawing false; });canvas.addEventListener(touchstart, (e) { e.preventDefault(); isDrawing true; const p getPos(e); drawAt(p.x, p.y); });canvas.addEventListener(touchmove, (e) { e.preventDefault(); if (!isDrawing) return; const p getPos(e); drawAt(p.x, p.y); });canvas.addEventListener(touchend, (e) { e.preventDefault(); isDrawing false; });document.getElementById(modeErase).onclick () { mode erase; };document.getElementById(modeRestore).onclick () { mode restore; };document.getElementById(resetBtn).onclick () { drawScene(); };document.getElementById(downloadBtn).onclick () {const link document.createElement(a);link.download 新背景合成图.png;link.href canvas.toDataURL(image/png);link.click();};// 初始化画布drawScene();/script/body/html---方案二一键更换电脑桌面壁纸Python 版适用场景想制作一个桌面端软件点击图片自动设为电脑壁纸。使用方法复制代码保存为 change_wallpaper.py运行后选择图片文件夹双击即可更换系统壁纸支持 Windows / macOS / Linux。pythonimport osimport tkinter as tkfrom tkinter import filedialog, Listbox, Scrollbar, Label, Framefrom PIL import Image, ImageTk # 需安装pip install Pillowimport ctypesimport subprocessimport platformclass WallpaperChanger:def __init__(self, root):self.root rootroot.title(️ 桌面壁纸更换器)root.geometry(420x550)root.configure(bg#2b2b3b)self.folder_path self.image_list []# UILabel(root, text选择图片文件夹, bg#2b2b3b, fg#fff, font(Arial, 14)).pack(pady10)btn tk.Button(root, text 浏览文件夹, commandself.load_folder, bg#4f46e5, fgwhite, padx20, pady5, border0)btn.pack(pady5)# 列表框frame Frame(root, bg#1e1e2e)frame.pack(pady10, filltk.BOTH, expandTrue, padx20)scroll Scrollbar(frame)scroll.pack(sidetk.RIGHT, filltk.Y)self.listbox Listbox(frame, yscrollcommandscroll.set, bg#3b3b58, fgwhite,selectmodetk.SINGLE, font(Arial, 11), height15, border0)self.listbox.pack(filltk.BOTH, expandTrue)scroll.config(commandself.listbox.yview)self.listbox.bind(Double-Button-1, self.set_wallpaper)self.preview_label Label(root, text双击图片名称即可更换, bg#2b2b3b, fg#9ca3af)self.preview_label.pack(pady5)def load_folder(self):path filedialog.askdirectory()if not path: returnself.folder_path pathself.listbox.delete(0, tk.END)self.image_list []exts (.jpg, .jpeg, .png, .bmp, .gif)for f in os.listdir(path):if f.lower().endswith(exts):self.image_list.append(f)self.listbox.insert(tk.END, f)self.preview_label.config(textf找到 {len(self.image_list)} 张图片)def set_wallpaper(self, eventNone):selection self.listbox.curselection()if not selection: returnfilename self.image_list[selection[0]]filepath os.path.join(self.folder_path, filename)sys_name platform.system()try:if sys_name Windows:ctypes.windll.user32.SystemParametersInfoW(20, 0, filepath, 3)elif sys_name Darwin: # macOSscript ftell application Finder to set desktop picture to POSIX file {filepath}subprocess.run([osascript, -e, script], checkTrue)elif sys_name Linux:# GNOME / KDE 通用尝试cmd fgsettings set org.gnome.desktop.background picture-uri file://{filepath}subprocess.run(cmd, shellTrue)self.preview_label.config(textf✅ 已更换: {filename}, fg#4ade80)except Exception as e:self.preview_label.config(textf❌ 设置失败: {str(e)[:30]}, fg#f87171)if __name__ __main__:root tk.Tk()app WallpaperChanger(root)root.mainloop()---如何运行1. Web版新建一个 换背景.html 文件把方案一代码粘贴进去双击用浏览器打开。2. 桌面壁纸软件新建一个 壁纸更换.py 文件粘贴方案二代码先执行 pip install Pillow 安装依赖再双击运行。

相关新闻

5分钟掌握AutoUnipus:终极U校园自动答题指南

5分钟掌握AutoUnipus:终极U校园自动答题指南

5分钟掌握AutoUnipus:终极U校园自动答题指南 【免费下载链接】AutoUnipus U校园脚本,支持全自动答题,百分百正确 2024最新版 项目地址: https://gitcode.com/gh_mirrors/au/AutoUnipus 还在为U校园平台上堆积如山的网课必修题而烦恼吗?每天花费数…

2026/6/29 14:45:07阅读更多 →
苹果设备激活锁终极绕过指南:5分钟免费解锁iOS 15-16限制

苹果设备激活锁终极绕过指南:5分钟免费解锁iOS 15-16限制

苹果设备激活锁终极绕过指南:5分钟免费解锁iOS 15-16限制 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 你是否因为忘记Apple ID密码而无法使用自己的iPhone?或者购买的二手苹…

2026/6/29 14:45:07阅读更多 →
Windows系统优化终极指南:如何使用WinUtil一键完成软件安装与系统调优

Windows系统优化终极指南:如何使用WinUtil一键完成软件安装与系统调优

Windows系统优化终极指南:如何使用WinUtil一键完成软件安装与系统调优 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil 你是否厌倦…

2026/6/29 14:40:05阅读更多 →
9 系列 SUV 车型推荐:2026 旗舰新能源 SUV 全维度对比 智己 LS9 深度盘点

9 系列 SUV 车型推荐:2026 旗舰新能源 SUV 全维度对比 智己 LS9 深度盘点

摘要2026 年国内大型旗舰新能源 SUV 市场中,“9 系列” 已成为独立的高端细分赛道,普遍具备车长 5.2 米左右、轴距 3.1 米上下、大六座布局的特征,是各品牌技术集中落地的旗舰级产品。本文为 9 系列 SUV 车型推荐全维度指南,以智己…

2026/6/29 15:55:26阅读更多 →
Icarus Verilog深度解析:开源硬件验证工具的技术架构与实战指南

Icarus Verilog深度解析:开源硬件验证工具的技术架构与实战指南

Icarus Verilog深度解析:开源硬件验证工具的技术架构与实战指南 【免费下载链接】iverilog Icarus Verilog 项目地址: https://gitcode.com/gh_mirrors/iv/iverilog 在数字电路设计与验证领域,硬件描述语言的仿真工具选择直接影响着开发效率与项目…

2026/6/29 15:55:26阅读更多 →
终极漫画管理指南:如何用exhentai-manga-manager轻松整理海量漫画

终极漫画管理指南:如何用exhentai-manga-manager轻松整理海量漫画

终极漫画管理指南:如何用exhentai-manga-manager轻松整理海量漫画 【免费下载链接】exhentai-manga-manager ExHentai本地漫画标签管理阅读应用, ExHentai local manga tag-manager and reader 项目地址: https://gitcode.com/gh_mirrors/ex/exhentai-manga-manag…

2026/6/29 15:55:26阅读更多 →
如何快速完整下载任何网站:Python网站离线下载器终极指南

如何快速完整下载任何网站:Python网站离线下载器终极指南

如何快速完整下载任何网站:Python网站离线下载器终极指南 【免费下载链接】WebSite-Downloader A website downloader written with Python 项目地址: https://gitcode.com/gh_mirrors/web/WebSite-Downloader 你是否曾经想要将整个网站完整地保存到本地电脑…

2026/6/29 15:55:26阅读更多 →
终极黑苹果配置指南:三分钟搞定OpenCore EFI的完整解决方案

终极黑苹果配置指南:三分钟搞定OpenCore EFI的完整解决方案

终极黑苹果配置指南:三分钟搞定OpenCore EFI的完整解决方案 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在为复杂的黑苹果配置而头疼…

2026/6/29 15:55:26阅读更多 →
TAS5707数字音频功放寄存器配置详解与避坑指南

TAS5707数字音频功放寄存器配置详解与避坑指南

1. 项目概述与核心价值如果你正在设计一款需要高品质音频输出的产品,比如智能音箱、Soundbar、电视主板或者便携式蓝牙音箱,那么你大概率绕不开一类芯片:数字音频功率放大器。这类芯片的魅力在于,它将传统的模拟功放和DAC&#xf…

2026/6/29 15:50:25阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/29 3:27:55阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/29 2:19:08阅读更多 →
如何在3秒内从普通图片生成专业级法线贴图:DeepBump的终极指南

如何在3秒内从普通图片生成专业级法线贴图:DeepBump的终极指南

如何在3秒内从普通图片生成专业级法线贴图:DeepBump的终极指南 【免费下载链接】DeepBump Normal & height maps generation from single pictures 项目地址: https://gitcode.com/gh_mirrors/de/DeepBump 还在为3D建模中的纹理制作而烦恼吗?…

2026/6/29 0:01:47阅读更多 →
OCAuxiliaryTools:终极OpenCore配置工具,让黑苹果安装从未如此简单!

OCAuxiliaryTools:终极OpenCore配置工具,让黑苹果安装从未如此简单!

OCAuxiliaryTools:终极OpenCore配置工具,让黑苹果安装从未如此简单! 【免费下载链接】OCAuxiliaryTools Cross-platform GUI management tools for OpenCore(OCAT) 项目地址: https://gitcode.com/gh_mirrors/oc/OCA…

2026/6/29 0:01:47阅读更多 →
终极Windows 11精简指南:使用tiny11builder快速创建纯净系统镜像

终极Windows 11精简指南:使用tiny11builder快速创建纯净系统镜像

终极Windows 11精简指南:使用tiny11builder快速创建纯净系统镜像 【免费下载链接】tiny11builder Scripts to build a trimmed-down Windows 11 image. 项目地址: https://gitcode.com/GitHub_Trending/ti/tiny11builder 你是否厌倦了Windows 11系统自带的20…

2026/6/29 0:01:47阅读更多 →