pixel2motion — ロゴPNGをSVGアニメーションに自動変換するAIスキル動いた
PNG/JPG/WebPのロゴをラスターからSVGへ自動トレースし、CSSアニメーション付きHTMLデモとコマ送り証拠画像まで作れるコマンド群(Codex/Claude Code向けAgent Skill)。付属トレーサーだけでIoU 0.97前後のSVGが1コマンドで得られた。
この日に実際に動かした結果です。内容の誤りに気づかれた場合はお問い合わせください。確認のうえ訂正します。
pixel2motion を使う前に分かること
| 必要なもの | 追加で用意するものは無し(無料の範囲で動いた) |
|---|---|
| 動かした環境 | Python 3.11 / venv(このマシンに直接、Dockerデーモンが使えなかったため)。 |
| 日本語 | 画面・文書は英語 |
| 確認日 | 2026-09-12(この日に実際に動かした) |
pixel2motion の使い方
やること:手元のロゴPNG1枚から、自動トレースでSVG化し、フィット精度の確認、CSSアニメーション付きHTMLデモの生成、コマ送りの証拠画像作成までを一通り行う。
venvを作り、Pillow・numpy・Playwrightを入れる。
python3 -m venv .venv .venv/bin/pip install pillow numpy playwrightpip installが成功し、pillow/numpy/playwrightが入る。
ロゴのラスター画像を scripts/raster_logo_trace.py に渡すと、色ごとに輪郭をトレースしたSVGと元画像とのフィット率(IoU)が1コマンドで出る。
.venv/bin/python scripts/raster_logo_trace.py source.png --out outputsoutputs/logo.svg が生成され、標準出力の metrics.iou に 0.966 のような数値が出る。
生成SVGを実ブラウザで描画し直し、元画像に重ねた水色オーバーレイでズレを目視確認する。rootでChromeを動かす環境では --no-sandbox を足したラッパーをCHROME_BINに指定する。
export CHROME_BIN=/tmp/verify-pixel2motion/chrome-nosandbox.sh .venv/bin/python scripts/render_overlay.py outputs/logo.svg source.png --out outputs/fit_iterations/01_overlay.png --render-out outputs/final_render.png --report outputs/fit_metrics.jsonIoU=0.8931 のような行が標準出力に出て、outputs/fit_iterations/01_overlay.png にオーバーレイ画像ができる。
SVGのパーツに付けたid(例: #mark, #dot)を使って自分でmotion.cssを書き、動くHTMLデモを1コマンドで生成する。
.venv/bin/python scripts/animate_svg_showcase.py outputs/logo.svg --css motion.css --out outputs/logo_motion.html --title "Test Logo Motion" --duration-hint 900outputs/logo_motion.html が生成され、ブラウザで開くと再生・スロー再生・速度調整のコントロール付きで動く。
Playwrightで ?t=<ms> ごとに時刻を止めてスクリーンショットを撮り、コマ送りの証拠画像と最終コマの差分を残す。
.venv/bin/python scripts/capture_motion_frames.py outputs/logo_motion.html --times 0,150,300,500,720 --out outputs/motion_frames --strip outputs/motion_strip.png --compare-final outputs/final_render.pngoutputs/motion_strip.png に5コマが並んだフィルムストリップができ、標準出力に最終コマと静止画の差分(mean/max)が出る。
最後まで通した時に出たもの(実際の出力)
captured t=0ms -> outputs/motion_frames/frame_000000ms.png captured t=150ms -> outputs/motion_frames/frame_000150ms.png captured t=300ms -> outputs/motion_frames/frame_000300ms.png captured t=500ms -> outputs/motion_frames/frame_000500ms.png captured t=720ms -> outputs/motion_frames/frame_000720ms.png strip -> outputs/motion_strip.png final-frame diff: mean=2.808 max=225.0 pixels>=25: 2.378%
pixel2motion の良かった点
- raster_logo_trace.py に平坦な色のロゴを渡すだけで、パスを1行も書かずにIoU 0.966という高精度なSVGトレースが1コマンドで返ってきた
- トレース→フィットQA(オーバーレイ画像+IoU)→アニメーション付きHTML生成→コマ送り撮影、と工程がスクリプトごとに分かれていて、途中の成果物(logo.svg, fit_metrics.json, logo_motion.htmlなど)を都度自分の目で確認できる
- capture_motion_frames.py は ?t=<ms> でアニメーションを指定時刻に一時停止させてから撮影するため、体感速度に左右されず毎回同じコマが撮れる(実際に同じ --times を2回撮っても同一の画像になった)
- APIキーもGPUも不要。venvとChromium/Playwrightだけで、ネットワークが使えない環境でもオフラインで最後まで動いた
pixel2motion の不便だった点
- render_overlay.py はChromeを直接subprocessで起動する実装で、rootユーザーで動かすとサンドボックス起動に失敗して素っ気ないCalledProcessErrorだけが出る。原因(サンドボックスとroot実行の相性)はエラーメッセージからは分からず、自分で --no-sandbox 付きのラッパースクリプトを用意する必要があった
- ラスター→SVGの本質的な『判断』(形が滑らかで破綻していないかの目視ジャッジ、パーツの意味的な分割)はSKILL.md(28KB)を読んだAIエージェントが担う設計で、スクリプト単体を叩くだけでは自動トレース止まりの結果しか得られない
詰まった点と、効いた対処
.venv/bin/python scripts/render_overlay.py outputs/logo.svg source.png --out outputs/fit_iterations/01_overlay.png --render-out outputs/final_render.png --report outputs/fit_metrics.jsonsubprocess.CalledProcessError: Command '['/opt/pw-browsers/chromium', '--headless=new', '--disable-gpu', '--hide-scrollbars', '--screenshot=/tmp/tmpomp3j2e7/shot.png', '--window-size=240,240', '--default-background-color=FFFFFFFF', 'file:///tmp/tmpomp3j2e7/wrap.html']' returned non-zero exit status 1.rootユーザーでChromeを直接起動するとサンドボックス関連で失敗する(Docker/CIでrootのまま動かすと踏みやすい)。`exec /path/to/chromium --no-sandbox "$@"` という1行のラッパースクリプトを作り、CHROME_BINにそのラッパーのパスを指定すると通った
確認した条件
| 確認日 | 2026-09-12 |
|---|---|
| 試した版 | e9faedb28930df0da2acf17da00c80730a78cfe8 (2026-08-21) |
| 実行環境 | Python 3.11 / venv(このマシンに直接、Dockerデーモンが使えなかったため)。Chromeは事前インストール済みの /opt/pw-browsers/chromium をCHROME_BINに指定。フレーム撮影用のPlaywrightだけ、このマシンにキャッシュ済みのChromiumのビルド番号に合わせてpip版を1.56.0へ明示的に固定した(通常は `pip install playwright && playwright install chromium` でビルドが自動的に揃うため、これは検証環境固有の対応)。 |