Knowledge
ブラウザ完結の背景除去ライブラリ @imgly/background-removal の使い方と onnxruntime-web バージョン固定の落とし穴
@imgly/background-removal を使ってブラウザ上でAI背景除去を実現する方法を解説。WASM/ONNXパイプラインの仕組み、dynamic importによるバンドル最適化、そして onnxruntime-web のバージョン不一致で発生するクラッシュとその対策を紹介します。
1. @imgly/background-removal とは
@imgly/background-removal は、ドイツのメディア処理ライブラリ会社 IMG.LY が開発・OSS公開したブラウザ専用の背景除去ライブラリです。 画像をサーバーへ送らず、ブラウザ上で完結して処理できるため、 プライバシーを重視するユースケースに適しています。
内部では onnxruntime-web を使い、 ONNX形式のAIモデルをWASM(WebAssembly)で実行します。 使用されるモデルは ISNet(Image Segmentation Network)という セグメンテーション用のDNNモデルです。
WASMバイナリとモデルファイルはCDNから動的に取得します。 初回のみダウンロードが発生し、以降はブラウザキャッシュで即起動します。 ライブラリ本体+WASMで数MB超になるため、dynamic import によるコード分割が必須です。
2. WASM/ONNX パイプラインの仕組み
処理フローは以下のとおりです。
ブラウザ
├─ JS バインディング(onnxruntime-web npm pkg)
└─ WASM バイナリ(CDN から fetch: ort-wasm-simd-threaded.wasm 等)
└─ ONNXモデル(isnet.onnx / isnet_fp16.onnx / isnet_quint8.onnx)
└─ 推論 → アルファマスク生成 → PNG合成(透過背景)処理の進捗は progress コールバックで受け取れます。 コールバックの引数 key でフェーズを判別できます。
key.startsWith('fetch')またはkey.startsWith('ort:load')→ モデル取得フェーズ- それ以外 → 推論フェーズ
UIでは「モデル読み込み中」と「処理中」を別々に表示することで、 ユーザーが処理の段階を把握しやすくなります。
3. 実際の使い方
① dynamic import(バンドル最適化)
トップレベルで import するとビルド時に全バンドルされてしまいます。 実行タイミングでのみ import することでバンドルサイズを削減できます。
// NG: トップレベルに書くとビルド時に全バンドルされる
import { removeBackground } from '@imgly/background-removal'
// OK: 実行タイミングでのみ import → バンドルサイズを削減
const { removeBackground } = await import('@imgly/background-removal')② progress コールバックでUIフェーズを管理
const resultBlob = await removeBackground(file, {
model: 'isnet',
progress: (key: string, current: number, total: number) => {
const pct = total > 0 ? Math.round((current / total) * 100) : 0
const isLoadPhase = key.startsWith('fetch') || key.startsWith('ort:load')
setPhase(isLoadPhase ? 'model-download' : 'processing')
setProgressPct(pct)
},
})③ model オプション(精度 vs 速度)
model オプションで精度と速度のバランスを選択できます。
'isnet'— 最高精度・最低速。フルFP32モデル。'isnet_fp16'— 標準精度・普通速度。省略時のデフォルト。'isnet_quint8'— 低精度・最高速。量子化モデル。
戻り値は Blob(MIME: image/png)です。URL.createObjectURL() でプレビューやダウンロードに使用できます。
4. onnxruntime-web バージョン不一致によるクラッシュ
発生したエラー:
Failed to create session: TypeError: r._OrtGetInputOutputMetadata is not a function.
Please check if the publicPath is set correctly.一見「publicPath の設定ミス」に見えますが、実際の原因はバージョン不一致です。
構造の解説:
@imgly/background-removal@1.7.0
└─ peerDependency: onnxruntime-web@1.21.0
↑ CDN配信のWASMバイナリはこのバージョン向けにビルドされている
npm install 後("^1.21.0" 指定時):
└─ onnxruntime-web@1.24.2(最新)がインストールされる
↑ JS APIが1.24.x仕様に変わり、1.21.0用WASMと不一致 → クラッシュ@imgly/background-removal はCDNからWASMバイナリを動的に取得します。 このバイナリは peerDependency に指定されたバージョン向けにビルドされています。^(キャレット)による範囲指定でインストールすると、 JSバインディングだけ新バージョンに更新されてWASMバイナリと不一致が生じます。
解決策:
// ❌ キャレット(範囲指定)— JSバインディングだけ更新されてWASMと不一致になる
"onnxruntime-web": "^1.21.0"
// ✅ 完全固定 — peerDependencyに記載のバージョンに合わせる
"onnxruntime-web": "1.21.0"peerDependency の確認方法:
npm info @imgly/background-removal peerDependencies
# → { 'onnxruntime-web': '1.21.0' }教訓: WASMやネイティブバイナリを含むライブラリは、 JSバインディングとバイナリのバージョンがペアで動作します。 CDNからバイナリを動的取得するライブラリでは ^ による範囲指定は危険です。 peerDependencyに指定されたバージョンを完全固定で使うことが重要です。
5. 精度チューニングと限界
model: 'isnet' が最大精度のオプションです。 感度・閾値・フェザリングなどの細かいパラメータは現時点のAPIには存在しません。 これ以上の精度向上はライブラリの設定では実現できません。
精度をさらに向上させたい場合の選択肢は以下のとおりです。
- サーバーサイドAPI(remove.bg、Adobe Firefly等): 精度は大幅に向上しますが、画像をサーバーへ送信するためプライバシー要件と相反します。
- プライバシー優先ユースケース: ブラウザ完結という制約を受け入れ、
isnetモデルでの精度を許容値として設計します。 背景が単色・コントラストが高い画像では十分な精度が得られます。
ブラウザ完結という強みとトレードオフの関係にある点を理解した上で、 ユースケースに合わせて技術選定を行うことが重要です。