smol-image-processor – microsserviço que normaliza para WebP após remover EXIF/metadados (Bun/Elysia)
(github.com/levish0)Ao receber uploads de imagens de usuários no backend, existem problemas que chegam silenciosamente juntos.
- JPEG pode conter coordenadas GPS, nome do modelo do dispositivo e horário da captura em EXIF
- Metadados de cor, como perfil ICC, também podem ser armazenados e distribuídos como estão
- Se JPEG, PNG, GIF e WebP entrarem misturados, o pipeline de armazenamento/CDN/renderização fica mais complexo
- Se apenas o EXIF orientation for tratado incorretamente, a imagem pode ser salva girada em 90°
O smol-image-processor é um microsserviço de função única que trata todos esses problemas de uma vez.
Como funciona
Ao enviar uma imagem para POST /process com multipart/form-data, a resposta sempre retorna em WebP. Sharp aproveita diretamente seu comportamento padrão de saída, que descarta metadados como EXIF de origem e perfil ICC. Porém, no caso do EXIF orientation, antes de remover os metadados ele aplica primeiro .rotate() aos pixels, preservando assim a orientação da imagem.
Há duas camadas de defesa.
- Limite de número de pixels (MAX_PIXELS): mesmo que o arquivo seja pequeno, imagens que se expandem para centenas de milhões de pixels na decodificação (decompression bomb) são bloqueadas com
limitInputPixelsdo Sharp. - Limite de número de frames (MAX_PAGES): evita DoS que esgota memória e CPU com GIFs/WebPs animados com centenas ou milhares de frames.
GIFs/WebPs animados são convertidos em WebP animado, com preservação do atraso entre frames e da contagem de loops. O canal alfa de PNG também é mantido.
Nos cabeçalhos da resposta são incluídos width, height, size, se é animado e o número de páginas da imagem processada, permitindo salvar diretamente no banco de dados sem uma etapa separada de extração de metadados.
Stack
- Runtime: Bun, framework HTTP: Elysia
- Processamento de imagem: Sharp (wrapper do libvips)
- Imagem Docker disponível (GHCR)
Início rápido
docker run --rm -p 6701:6701 ghcr.io/levish0/smol-image-processor
curl -F file=@photo.jpg http://localhost:6701/process -o clean.webp
Ainda não há comentários.