瀏覽器端 AI 摳圖技術實現詳解
前言
本文講解如何在瀏覽器端實現 AI 摳圖功能,無需後端服務器,完全在客户端完成圖像分割處理。核心使用 @imgly/background-removal 庫,基於 ONNX Runtime 和 WebAssembly 技術。
技術原理
核心技術棧
- @imgly/background-removal: 封裝好的圖像分割庫
- ONNX Runtime Web: 在瀏覽器中運行深度學習模型的引擎
- WebAssembly
- WebGL/GPU
工作流程
核心實現
1. 安裝依賴
npm install @imgly/background-removal
2. 模型加載
模型文件約 20-30MB,首次加載需要時間,但會被瀏覽器緩存:
import { preload, Config } from '@imgly/background-removal'
let modelLoaded = false
const RMBG_CONFIG: Config = {
// publicPath 使用默認配置,庫會自動從 CDN 加載模型
device: 'gpu', // 使用 GPU 加速
output: {
format: 'image/png',
quality: 1.0,
},
}
export async function loadModel(): Promise<void> {
if (modelLoaded) return
// 🍉
await preload(RMBG_CONFIG)
modelLoaded = true
console.log('✅ AI 模型加載完成')
}
關鍵點:
preload會下載並初始化 ONNX 模型- 模型包含神經網絡權重,用於圖像分割
- 加載一次後瀏覽器會緩存,下次訪問秒開
3. 背景移除核心實現
最簡單的用法,輸入 Blob 輸出 Blob:
import { removeBackground } from '@imgly/background-removal'
// 🍉 核心就這一句!
const resultBlob = await removeBackground(inputBlob, RMBG_CONFIG)
工作原理:
- 輸入圖片 Blob → ONNX 模型推理 → 輸出透明背景 PNG Blob
- 模型會分析每個像素的前景/背景概率,生成 Alpha 通道(透明度)
4. 完整示例
'use client'
import { useEffect, useState } from 'react'
import { preload, removeBackground, Config } from '@imgly/background-removal'
const config: Config = {}
export default function App() {
const [ready, setReady] = useState(false)
const [originalUrl, setOriginalUrl] = useState('')
const [resultUrl, setResultUrl] = useState('')
const [processing, setProcessing] = useState(false)
useEffect(() => {
preload(config).then(() => setReady(true))
}, [])
const handleFile = async (file: File) => {
setOriginalUrl(URL.createObjectURL(file))
setProcessing(true)
const resultBlob = await removeBackground(file, config)
setResultUrl(URL.createObjectURL(resultBlob))
setProcessing(false)
}
return (
<div style={{ padding: '20px' }}>
{!ready && <div>模型加載中...</div>}
<input type="file" accept="image/*" onChange={(e) => e.target.files?.[0] && handleFile(e.target.files[0])} />
{processing && <div>處理中...</div>}
<div style={{ display: 'flex', gap: '20px', marginTop: '20px' }}>
{originalUrl && (
<div>
<h3>原圖</h3>
<img src={originalUrl} alt="原圖" style={{ maxWidth: '400px' }} />
</div>
)}
{resultUrl && (
<div>
<h3>摳圖結果</h3>
<img src={resultUrl} alt="結果" style={{ maxWidth: '400px', background: 'repeating-conic-gradient(#ddd 0% 25%, white 0% 50%) 50% / 20px 20px' }} />
</div>
)}
</div>
</div>
)
}
參數説明
Config 配置參數
interface Config {
publicPath?: string // 模型文件路徑,默認從 https://staticimgly.com/@imgly/background-removal-data/1.7.0/dist/ 加載
debug?: boolean // 是否開啓調試模式,默認 false
device?: 'cpu' | 'gpu' // 使用 CPU 或 GPU,默認 'gpu',GPU在移動端可能無法加載需要使用CPU
model?: 'small' | 'medium' | 'large' // 模型大小,默認 'medium'
output?: {
format?: 'image/png' | 'image/jpeg' | 'image/webp' // 輸出格式,默認 'image/png'
quality?: number // 輸出質量 0-1,默認 1.0
type?: 'foreground' | 'background' | 'mask' // 輸出類型,默認 'foreground'
}
}
publicPath 説明:
- 不配置時,默認從
https://staticimgly.com/@imgly/background-removal-data/1.7.0/dist/下載(需要🪜) - 也可以從
https://staticimgly.com/@imgly/background-removal-data/1.7.0/package.tgz下載到本地使用 - 本地使用示例:
publicPath: '/models/'
removeBackground 參數
await removeBackground(
image: string | URL | File | Blob | ImageData, // 輸入圖片
config?: Config // 可選配置
): Promise<Blob> // 返回處理後的 Blob
輸入類型:
string: 圖片 URL 地址File: 文件對象(input[type=file])Blob: 二進制數據ImageData: Canvas ImageData 對象
返回值:
- 返回透明背景的 PNG Blob(或配置的其他格式)
技術細節
AI 模型是如何工作的?
@imgly/background-removal 使用的是 U²-Net 圖像分割模型:
- 輸入層:接收 RGB 圖片(任意尺寸)
- 編碼器:提取圖像特徵(邊緣、紋理、形狀)
- 解碼器:生成分割掩碼(Mask)
- 輸出層:每個像素的前景概率(0-1)
模型訓練數據包含數十萬張人像、物品、動物等標註圖片,所以能準確識別主體。
為什麼在瀏覽器能運行深度學習?
關鍵技術是 ONNX Runtime Web:
- ONNX:開放神經網絡交換格式,跨平台的模型標準
- WebAssembly:接近原生速度的字節碼,比 JavaScript 快 10-20 倍
- WebGL:利用 GPU 進行並行計算,矩陣運算速度提升 100 倍+
流程:
PyTorch/TensorFlow 訓練模型 → 導出為 ONNX → ONNX Runtime 加載 → WebAssembly 執行
性能數據
實測數據(1920x1080 圖片):
| 設備 | 處理時間 | 內存佔用 |
|---|---|---|
| 桌面端 GPU | 2-3 秒 | ~200MB |
| 桌面端 CPU | 8-12 秒 | ~150MB |
| 移動端 | 15-30 秒 | ~100MB |
使用注意
- 首次加載需下載 20-30MB 模型文件,之後會被瀏覽器緩存
- 人像摳圖精度 95%+,物品/動物 85%+
- 所有處理在瀏覽器本地完成,圖片不會上傳服務器
- 支持批量處理,建議串行避免內存溢出
實際應用
基於這套技術實現的兩個工具:
- AI 智能摳圖 - 一鍵移除背景,輸出透明 PNG
- AI 證件照製作 - 自動摳圖 + 更換背景色,生成標準證件照