Algorithm & UI/UX
ブラウザだけで完結する
背景切り抜き実装のハック
「写真をサーバーに送りたくない」というニーズに応えるため、すべての画像処理をクライアントサイドのCanvas APIで完結させています。今回はその中核となるロジックを抽出して解説します。
このツールの入力から出力まで
現行コードの確認日:
- 入力
- 写真を選び、背景として消したい場所を手でなぞります。
- 処理
- 円形のブラシで合成モードdestination-outを使い、既存画素のアルファを消します。Undo用にはPNGのデータURLを保持します。
- 出力
- 出力は長辺最大 2000px の透明 PNG です。
まず確認する点:AIによる人物認識は使いません。素早い軌跡には隙間が出ることがあるため、背景色を変えて輪郭と消し残しを確認します。
仕上がりの例
猫の写真の背景を取り除き、透過PNGにした例です。
市松模様は透明部分を示す表示用の背景です。ツールで保存する透過PNGには含まれません。
掲載画像はサイトにある既存の公開作例です。保存済みの資料では運営者の愛猫の写真を使用しています。今回の確認日が、この作例を実行した日を表すわけではありません。
保存済み検証記録の条件を見る
資料の種類は「既存の公開作例」です。公開作例と保存済み記録で素材や色などが異なる場合があるため、下の数値は保存済み検証記録の条件として読んでください。
猫とソファのクッションを残し、背後の室内の背景を取り除いた透過PNGの例です。
- 記録の入力画像
- 600×667px (JPEG)
- 記録の出力画像
- 600×667px (PNG)
この作例には操作値の記録がないため、同じ設定で再現できるとは断定しません。本文の数値は現行の実装仕様です。
資料ファイルの作成日は実行日として扱っていません。個別端末の処理速度や、ほかの写真に対する検出・加工の精度を測定した資料でもありません。
実装の確認箇所:src/pages/image/remove-bg/index.astro。以下のコード抜粋と出力条件は、この本番実装に基づいて説明します。
仕組みを読み進めるときは、Canvas APIと画像処理(画像寸法、drawImage、画素と透明度の扱い)、File APIとObject URL(選んだ画像の読み込みとBlob URLの解放)が参考になります。
1. destination-out による「透明なペン」の実装
Canvasで背景を消す際、一般的な「白や黒で塗る」方法では透明化はできません。このツールでは globalCompositeOperation プロパティに destination-out を設定することで、なぞった部分を「削り取る(透明にする)」処理を実現しています。
この設定により、描画済みのピクセルが新しい描画と重なった部分だけ完全に除去されるため、直感的な消しゴム機能が作れます。
円形の範囲を消す最小例です。ctx は画像を描いた Canvas のコンテキスト、diameter は画像上のピクセル数です。
function eraseCircle(ctx, x, y, diameter) {
ctx.save();
ctx.globalCompositeOperation = 'destination-out';
ctx.beginPath();
ctx.arc(x, y, diameter / 2, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
} 2. 端末負荷を抑えるスマート・リサイズ
近年のスマホ写真は数千万画素に及びますが、そのままCanvasに展開するとメモリ不足でブラウザがクラッシュするリスクがあります。本ツールでは、長辺 2000px 以下に縮小する処理を採用しています。
読み込み時にアスペクト比を維持したまま、最大長辺を特定の閾値に制限することで、後続の描画に使う画素数を減らしています。メモリ不足や遅延を防ぐ保証ではありません。
3. HEIC/HEIF形式のオンザフライ変換
このツールでは、HEICを選んだ場合はブラウザ内で別の画像形式に変換してから編集します。UXを損なわないよう、ダイナミック・インポートを活用して変換ライブラリを必要な時だけ読み込み、ブラウザ内でPNGに変換するフローを組み込んでいます。
出力の仕様と確認する点
AI による自動判定ではなく、なぞった箇所を手動で消すツールです。ブラシ径は処理画像上の 5〜100px。点を円として描く方式なので、速くなぞると隙間が残る場合があります。
Undo 用に PNG のデータ URL を保持し、履歴の配列は現在状態を含め最大 11 件になります。Undo は画像を読み直して戻すため、編集中の元データもメモリに残ります。
出力は長辺最大 2000px の透明 PNG です。消し残しは白背景上では見えにくい場合があるため、透明部分と輪郭を確認します。印刷サービスごとの解像度や入稿条件を判定する機能はありません。
