smol-image-processor – EXIF/メタデータを削除してWebPに正規化するマイクロサービス(Bun/Elysia)
(github.com/levish0)バックエンドでユーザー画像のアップロードを受け付ける際、静かについてくる問題があります。
- JPEGにはGPS座標、デバイスのモデル名、撮影時刻がEXIFとして含まれていることがある
- ICCプロファイルのようなカラーメタデータもそのまま保存・配布される可能性がある
- JPEG、PNG、GIF、WebPが混在して入ってくると、保存/CDN/レンダリングパイプラインが複雑になる
- EXIF orientationの処理を誤るだけで、画像が90°回転したまま保存される
smol-image-processorは、これらの問題を一括処理する単一責務のマイクロサービスです。
動作方式
POST /process に multipart/form-data で画像をアップロードすると、常にWebPがレスポンスとして
返されます。Sharpのデフォルト出力動作が、ソースのEXIF、ICCプロファイルなどのメタデータを
破棄する特性をそのまま活用しています。ただし、EXIF orientationはメタデータを削除する
前に .rotate() で先にピクセルへ適用し、画像の向きが維持されます。
防御レイヤーは2つあります。
- ピクセル数制限(MAX_PIXELS): ファイルサイズが小さくても、デコード時に数億ピクセルまで
膨張する画像(decompression bomb)をSharpのlimitInputPixelsで遮断します。 - フレーム数制限(MAX_PAGES): 数百〜数千フレームのアニメーションGIF/WebPによって
メモリ・CPUを枯渇させるDoSを防ぎます。
アニメーションGIF/WebPはanimated WebPに変換され、フレームディレイとループ回数が
保持されます。PNGのアルファチャンネルもそのまま維持されます。
レスポンスヘッダーには、処理後画像のwidth、height、size、animatedかどうか、ページ数が
含まれており、別途メタデータ抽出ステップなしでDBにそのまま保存できます。
スタック
- Runtime: Bun、HTTPフレームワーク: Elysia
- 画像処理: Sharp(libvipsラッパー)
- Dockerイメージ提供(GHCR)
クイックスタート
docker run --rm -p 6701:6701 ghcr.io/levish0/smol-image-processor
curl -F file=@photo.jpg http://localhost:6701/process -o clean.webp
まだコメントはありません。