canvas.toBlob()でavifに変換できない
from ✅HAMPU: 画像アップロード機能 #137
まだcanvasでavifに変換できない
https://developer.mozilla.org/ja/docs/Web/API/HTMLCanvasElement/toBlob
GPT-5.icon代替手段は以下の5つが現実的。
1. WebAssemblyエンコーダを使う
libavif を Emscripten でコンパイルした WASM ライブラリを使う
入力: canvas → ImageData or PNG → WASMでAVIFに変換
例: Squoosh がこの方式を採用
2. WebCodecs API (一部ブラウザ限定)
ImageEncoder で avif を指定するとエンコード可能なブラウザもある
モバイルの最新 Chrome 系は対応しつつあるが Safari/Firefox は未整備
3. Service Worker 経由で変換リクエスト
クライアント側で canvas を PNG/JPEG に落とす
Service Worker 内で WASM エンコーダ呼び出して AVIF に変換
メモリ管理や処理の分離がしやすい
4. WebAssembly + Web Worker (オフメインスレッド)
直接メインスレッドでAVIF変換すると処理が重すぎる
Worker内でlibavif-wasmを動かして変換、メインにBlobを返す
5. サーバー変換を併用するハイブリッド
ブラウザではPNG/JPEG/WebPに変換し一時アップロード
サーバー側で cavif-rs や libavif でAVIFに再変換
クライアント負荷を下げつつAVIFを配信
Workersでやるなら選択肢はこれ:
1. サーバー変換 (選択肢5の発展形)
ブラウザから PNG/JPEG/WebP をアップロード
Worker 内で AVIF に変換
返却 or R2/S3 に保存
→ これが Workers 向けの現実的解
2. Workers + WASM ライブラリ
libavif を WASM ビルドして Workers に組み込む
受け取った画像を WASM で AVIF に変換
→ 実行時間は長いので CPU time/メモリ制限に注意
3. Cloudflare Images や Stream (外部サービス連携)
Cloudflare Images にアップロードすると自動的に AVIF 配信される
Workers 側は変換せず「転送役」だけにする
→ 実装が簡単、コストは追加
確実に将来的には canvas.toBlob("image/avif") もサポートされます。理由は次の通り:
デコード(表示)は既に主要ブラウザで対応済み
AVIF画像はChrome, Safari, Firefox すべてで表示できるようになっている。
→ 表示できるなら、次はエンコード(toBlob/toDataURL)が自然な流れ。
仕様上は既に許可されている
MDNのドキュメントでも toBlob("image/avif") のシグネチャは明記済み。
→ 実装待ちの段階。
WebCodecs APIでのAVIFエンコードが進行中
new ImageEncoder({type: "image/avif"}) が動くブラウザが出始めている。
WebCodecsで可能なら、Canvas APIでも統一される可能性が高い。
歴史的な前例
JPEG/PNG → WebP → AVIF と、すべて「decode対応→encode対応」の順で進んできた。
ただしSafariは新フォーマット対応が遅れがちなので、全ブラウザで揃うのは数年かかるかもしれません