teqo/docs/changelog/2026-08-15-img-resize.md
2026-08-16 00:49:24 -03:00

2.6 KiB
Raw Blame History

Recently resolved (2026-08-15): IMG-RESIZE — otimizador local de imagens para o draft do site de campanha (fotos pesadas travavam o PenPot). pnpm images:resize (scripts/resize-images.mjs) aceita múltiplos paths (arquivos ou pastas, varridas recursivamente), aplica EXIF-rotation, remove metadados e gera DUAS versões por padrão com largura por formato: .avif em 3840px (2× tela desktop, quality 60) para o site, e .webp em 1920px (1×, quality 75 — ¼ dos pixels) para PenPot/navegadores antigos, sem upscaling (fit: 'inside'); conjunto/qualidade/pasta via --format avif,webp / --quality / --out (default public/), --max-width sobrepõe todos. --remove-bg remove o fundo com IA 100% local (@imgly/background-removal-node, onnxruntime; 1ª execução baixa o modelo ~40 MB, depois cache; intermediário PNG explícito — o pacote 1.4.5 não faz sniffing de magic bytes e morre com blob sem type); jpeg (sem alpha) é achatado em branco. pnpm images:fill (scripts/fill-image.mjs) completa/corrige regiões com FLUX-2-dev no DeepInfra (DEEPINFRA_API_KEY no .env.local): --extend <px|%> cresce o canvas pela base, preenche a faixa de branco e gera a máscara dela sozinho (foto de Lula cortada no peito sem espaço abaixo — o caso de uso), ou --mask <png> para inpaint arbitrário (branco = regenerar, preto = manter); prompt default pronto para completar corpo, --steps (default 28, guidance 30), máscara enviada no canal alpha do PNG (transparente = regenerar — convenção FLUX-2 nativa; descobrimos na marra que o wrapper OpenAI-images/edits do DeepInfra ignora o size e sempre devolve 1024×1024 — o endpoint nativo /v1/inference/black-forest-labs/FLUX-2-dev aceita múltiplos de 64 e devolve na mesma dimensão), canvas com padding opaco até múltiplo de 64 (padToMultipleOf64) recortado após a geração, downscale de fotos enormes (27 MP) para orçamento pré-pad de 1.8 MP — o endpoint nativo recusa >~2 MP e cobra por pixel, master PNG em data/ai-fill/ (gitignored) e cadeia o resize (avif+webp) no resultado via engine compartilhada runResizeImages (exportada de resize-images.mjs com guard de argv; --no-resize corta a cadeia). Derivação pura em scripts/lib/imageResize.mjs (parse fail-closed, alias jpg→jpeg, maxWidthFor/qualidade por formato) e scripts/lib/imageFill.mjs (parseExtendPx, extendedCanvas, padToMultipleOf64, prompts default), unit-testadas em tests/unit/imageResize.unit.spec.ts + tests/unit/imageFill.unit.spec.ts. Sem migration/access/Consent/UI/schema.