smol-image-processor – Mikroservice zum Normalisieren nach WebP durch Entfernen von EXIF/Metadaten (Bun/Elysia)
(github.com/levish0)Beim Entgegennehmen von Bild-Uploads von Nutzern im Backend gibt es Probleme, die stillschweigend mitkommen.
- In JPEGs können GPS-Koordinaten, Gerätemodellnamen und Aufnahmezeitpunkte als EXIF enthalten sein
- Farbmetadaten wie ICC-Profile können ebenfalls unverändert gespeichert und ausgeliefert werden
- Wenn JPEG, PNG, GIF und WebP gemischt hereinkommen, wird die Speicher-/CDN-/Rendering-Pipeline komplexer
- Schon eine falsch behandelte EXIF-Orientation kann dazu führen, dass ein Bild um 90° gedreht gespeichert wird
smol-image-processor ist ein Mikroservice mit einer einzigen Aufgabe, der diese Probleme gesammelt verarbeitet.
Funktionsweise
Wenn ein Bild per multipart/form-data an POST /process hochgeladen wird, kommt als Antwort immer WebP
zurück. Dabei wird direkt das Standard-Ausgabeverhalten von Sharp genutzt, bei dem Metadaten wie
source EXIF, ICC-Profile usw. verworfen werden. Allerdings wird die EXIF-Orientation vor dem Entfernen
der Metadaten zunächst mit .rotate() auf die Pixel angewendet, damit die Bildausrichtung erhalten bleibt.
Es gibt zwei Schutzebenen.
- Begrenzung der Pixelzahl (MAX_PIXELS): Selbst wenn die Dateigröße klein ist, werden Bilder, die sich beim Dekodieren auf Hunderte Millionen Pixel aufblähen (decompression bomb), durch Sharps
limitInputPixelsblockiert. - Begrenzung der Frame-Anzahl (MAX_PAGES): Verhindert DoS durch animierte GIFs/WebPs mit Hunderten bis Tausenden Frames, die Speicher und CPU erschöpfen.
Animierte GIFs/WebPs werden in animiertes WebP umgewandelt, wobei Frame-Delays und Loop-Anzahl erhalten bleiben.
Auch der Alpha-Kanal von PNG bleibt unverändert erhalten.
Im Response-Header sind width, height, size, ob das Bild animiert ist, und die Seitenanzahl des verarbeiteten Bildes enthalten, sodass es ohne zusätzlichen Schritt zur Metadatenextraktion direkt in der DB gespeichert werden kann.
Stack
- Runtime: Bun, HTTP-Framework: Elysia
- Bildverarbeitung: Sharp (libvips-Wrapper)
- Docker-Image verfügbar (GHCR)
Schnellstart
docker run --rm -p 6701:6701 ghcr.io/levish0/smol-image-processor
curl -F file=@photo.jpg http://localhost:6701/process -o clean.webp
Noch keine Kommentare.