网页端, 40mb离线模型, 自动抠图, 不用 Python,不用服务器,不用 API Key, 不用显卡

一张照片,点一下抠完。

不用后端,不用 GPU 服务器,不用调 API。

浏览器直接搞定。

我机器是可是个老古董, AMD5500, 用40mb的模型, 一次抠图8s多。

核心代码:

bash 复制代码
import { removeBackground } from "https://cdn.jsdelivr.net/npm/@imgly/background-removal@1.7.0/+esm"

const file = document.getElementById("file").files[0]
const png = await removeBackground(file)
URL.createObjectURL(png)

图选完,几秒出透明 PNG。图不离开本机。

流程图

bash 复制代码
    上传图片
        │
        ▼
  加载 ISNet ONNX 模型
        │
        ▼
  WebGPU / WebGL / WASM 推理
        │
        ▼
  输出透明 PNG(Blob)
        │
        ▼
  棋盘格预览 + 下载

1.1 痛点

做电商,天天抠图。

一张一张用 PS,抠头发抠花边,半小时一张。

网上抠图工具,图传到人家服务器。

隐私没了,还要付费。

能不能浏览器本地跑?

@imgly/background-removal,纯前端,零后端。

1.2 包简介

GitHub 约 6.8 千星。

底层 ONNX Runtime Web,推理模型 ISNet。

| 模型 | 大小 | | :-- | :-- | | isnet_fp16 | ~80MB,默认推荐 | | isnet_quint8 | ~40MB,最快够用 |

设备自动选:WebGPU → WebGL → WASM

有显卡跑显卡,没显卡跑 CPU。

1.3 CDN 引入

bash 复制代码
<script type="module">
import { removeBackground } from "https://cdn.jsdelivr.net/npm/@imgly/background-removal@1.7.0/+esm"
</script>

jsDelivr 的 +esm 自动打包,国内直连。

不用 npm,不用 publicPath,库自动从 CDN 拉模型。

1.4 模型精度

ISNet 是专门做图像分割的模型。

isnet_fp16,80MB,精度最高。

isnet_quint8,40MB,量化版,速度快一倍,精度略有损失。

人像抠图两个都够用,发丝细节选 FP16。

物品抠图选 QuInt8,速度快,肉眼看不出差别。

1.5 设备自动降级

bash 复制代码
WebGPU → WebGL → WASM

有 WebGPU 用 WebGPU,跑最快。

没有 WebGPU,降级 WebGL。

连 WebGL 都没有,降级 WASM 纯 CPU 跑。

整个过程自动判断,开发者不用写兼容代码。

1.6 进度回调

bash 复制代码
progress: (key, current, total) => {
  const pct = Math.round((current / total) * 100)
}

key 告诉你当前阶段:

bash 复制代码
download    下载模型
load        加载模型
run         前向推理
postprocess 后处理

total 为 0 时表示该阶段无进度信息,忽略即可。

1.7 输出格式

bash 复制代码
// PNG,透明背景
removeBackground(file, { output: { format: "image/png" } })

// JPEG,白底,可调 quality
removeBackground(file, { output: { format: "image/jpeg", quality: 0.85 } })

// WebP,体积小
removeBackground(file, { output: { format: "image/webp", quality: 0.9 } })

| 格式 | 透明 | 体积 | | :-- | :-- | :-- | | PNG | ✓ | 最大 | | JPEG | ✗ | 最小 | | WebP | ✓ | 中等 |

默认输出 PNG。

1.8 输出类型

bash 复制代码
// 主体(默认)
removeBackground(file, { output: { type: "foreground" } })

// 背景
removeBackground(file, { output: { type: "background" } })

// 黑白遮罩图
removeBackground(file, { output: { type: "mask" } })

遮罩图可以做二次处理,比如换底色。

1.9 换底色

拿到透明 PNG 后,用 canvas 合成底色:

bash 复制代码
function addColorBg(png, color) {
  const img = new Image()
  img.onload = () => {
    const c = document.createElement("canvas")
    c.width = img.width; c.height = img.height
    const ctx = c.getContext("2d")
    ctx.fillStyle = color
    ctx.fillRect(0, 0, c.width, c.height)
    ctx.drawImage(img, 0, 0)
    c.toBlob(blob => URL.createObjectURL(blob))
  }
  img.src = URL.createObjectURL(png)
}

addColorBg(png, "#cc0000")  // 红底证件照

1.10 浏览器缓存

第一次调用下载 80MB 模型文件。

浏览器自动缓存到 disk cache。

第二次打开页面,秒级完成。

清缓存会重新下载。

总结

  • @imgly/background-removal:纯前端,一行代码

  • ISNet 模型:ONNX,人像物品通吃

  • WebGPU:有显卡 3 秒出图

  • 棋盘格预览:透明一眼见

  • 换底色:再加 10 行代码

  • 零后端:隐私不出本机

现在有个问题, 背景复杂的时候, 抠图会多扣,

所以, 再过2天, 本周我会发布一个带选取的版本, 抠图更丝滑

相关推荐
梦曦i1 小时前
修复 .uvue 页面路径残留问题
前端·vite
nicole bai1 小时前
vue前端全局图标闪一下的问题
前端·vue.js
ly76891 小时前
磁盘 I/O 延迟突增:用 iostat、blktrace 与火焰图定位到具体调用栈
java·linux·前端·数据库·iostat·磁盘 i/o·blktrace
IT_陈寒1 小时前
Redis并发写入踩坑记录:别让超时设置坑了你
前端·人工智能·后端
晨枫阳1 小时前
Client authentication(客户端授权)开关与OAuth2 PKCE的深刻理解
前端·安全
福兮说1 小时前
在浏览器里写一个“够用就好“的 Excel 公式求值器
前端·javascript·excel·编译原理
Bs_MoneyMagnet1 小时前
基于springboot+vue的图书馆预约系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·毕业设计·图书管理系统·计算机毕业设计
志尊宝1 小时前
Vue3 零基础每日笔记(027):组件上的 v-model——让自定义组件也能双向绑定
前端·javascript·vue.js·笔记·html5
console.log('npc')1 小时前
03 — 核心框架:App 与中间件
后端·node.js·express