Skip to content

Aceitar PNG/WebP e melhorar mensagem de erro para JPEG progressivo (icebox - melhorias DX) #45

Description

@rhfranzoni

Origem

@rhfranzoni via Claude Code (conversa interna 2026-05-28) — sub-issue derivada da issue mãe em nfe/dfetech-product-invoice-api. Marcada como icebox / não bloqueia MVP — a integração end-to-end de logo na DANFE funciona sem nenhuma alteração no DanfeSharp (a API atual já é suficiente). Esta sub-issue cobre dois pontos de polimento.

Contexto

A biblioteca DanfeSharp já oferece API funcional para injeção de logo no DANFE via Danfe.cs:86-123AdicionarLogoImagem(Stream) e AdicionarLogoPdf(Stream). Renderiza em todas as páginas via XObject único (custo de bytes mínimo) com posicionamento adaptativo (horizontal → max 14pt altura; vertical → scaled to container).

Duas limitações conhecidas que valem ser tratadas em um momento futuro:

  1. Sem suporte a PNG/WebP nativo. A lib aceita apenas JPEG não-progressivo ou PDF (first page). PNG falha com InvalidOperationException lançada em Danfe.cs:91. A solução em produção contorna isso convertendo na ingestão (dfetech-tax-payers-api re-encoda para JPEG não-progressivo via ImageSharp) — funciona perfeitamente para o caso NFe.IO. Mas para consumers externos do DanfeSharp (a lib é open-source / pode ter consumidores fora da NFe.IO), suportar PNG e WebP nativamente seria uma melhoria importante de DX.

  2. Mensagem de erro genérica para JPEG progressivo. Quando o usuário tenta carregar um JPEG progressivo (codificação SOF2 em vez de SOF0 baseline), a mensagem atual é "O logotipo não pode ser carregado, certifique-se que a imagem esteja no formato JPEG não progressivo". Não há detecção ativa do marker SOF — o erro vem do PdfClown ao falhar no parse, e a mensagem é uma adivinhação razoável mas genérica. Idealmente queremos: detectar o marker SOF (0xFFC2 = progressive, 0xFFC0 = baseline) no header do JPEG antes de passar para o PdfClown, dando erro descritivo ("JPEG progressivo detectado (marker SOF2). DanfeSharp suporta apenas JPEG baseline (SOF0). Re-encode com 'jpegtran -copy none -optimize source.jpg dest.jpg' ou Pillow Image.save(progressive=False).").

Nenhuma dessas duas é crítica — ambas têm workaround. Por isso a issue fica como icebox.

Objetivo

(1) Suportar PNG e WebP como formatos de entrada nativos do AdicionarLogoImagem(Stream) — usuários da biblioteca podem passar PNG sem precisar pré-converter. (2) Quando o usuário passa um JPEG progressivo, a exception lançada inclui mensagem descritiva com diagnóstico do marker SOF detectado e sugestão concreta de comando para corrigir.

Escopo — Inclui

  • PNG/WebP support (item 1):
    • Investigar capability atual do PdfClown.NetStandard 0.2.0-beta para PNG (org.pdfclown.documents.contents.entities.Image.Get)
    • Se PdfClown não suporta nativamente: adicionar conversão inline via SixLabors.ImageSharp (mesma biblioteca usada no dfetech-tax-payers-api) antes de passar para Image.Get
    • Fixture nova: DanfeSharp.Test/Logos/PNG/Quadrado.png (e Horizontal/Vertical)
    • Tests novos em DanfeXmlTests ou novo LogoFormatTests.cs: gerar DANFE com PNG e verificar via PdfClown TextExtractor (a área do emitente preservada) + verificar XObject embedded
  • JPEG progressivo diagnostic (item 2):
    • Helper privado DetectJpegEncoding(Stream): peek nos primeiros bytes do stream, procurar marker SOF (0xFFC0 = baseline, 0xFFC2 = progressive), restaurar position do stream
    • Em AdicionarLogoImagem(Stream): se source for JPEG, chamar DetectJpegEncoding antes do Image.Get. Se progressive → lançar InvalidOperationException descritiva (com marker, sugestão de comando, link para issue)
    • Test: passar JPEG progressivo conhecido → verificar mensagem da exception
  • Documentação (README.md da lib):
    • Seção "Formatos suportados" com tabela: JPEG baseline (✓), JPEG progressive (✗ com explicação), PNG (✓ após esta change), WebP (✓ após esta change), PDF (✓)
    • Snippet de exemplo de uso de AdicionarLogoImagem(Stream)

Escopo — Não inclui

  • Suporte a SVG (requer raster intermediate, fora de scope)
  • Suporte a animated GIF / multi-frame imagens (DANFE é estático, sem sentido)
  • Mudança no posicionamento do logo na DANFE (já funciona)
  • Mudança no comportamento de PDF logo (já funciona)
  • Upgrade major do PdfClown (risco alto, escopo amplo — fazer separadamente se necessário)

Critérios de Aceitação

  • danfe.AdicionarLogoImagem(streamPng) carrega um PNG e renderiza no DANFE corretamente
  • danfe.AdicionarLogoImagem(streamWebp) carrega um WebP e renderiza no DANFE corretamente
  • danfe.AdicionarLogoImagem(streamJpgProgressive) lança InvalidOperationException com mensagem mencionando explicitamente "JPEG progressivo" e o marker SOF2 detectado
  • Mensagem da exception inclui pelo menos uma sugestão concreta de comando (jpegtran ou Pillow) para converter para baseline
  • Tests cobrindo PNG, WebP, JPEG baseline, JPEG progressive e PDF
  • README atualizado com tabela de formatos suportados e snippet de uso
  • Zero regressão em fixtures existentes (Quadrado.jpg, Horizontal.jpg, Vertical.jpg, Quadrado.pdf, Horizontal.pdf, Vertical.pdf — todos continuam funcionando)
  • dfetech-tax-payers-api continua convertendo para JPEG baseline na ingestão (não precisa mudar — a conversão estabiliza o formato, mesmo com DanfeSharp suportando PNG/WebP nativamente, é boa prática manter formato canônico no storage)

Dependências

  • Nenhuma — esta sub-issue é independente da issue mãe e da sub-issue de tax-payers-api
  • Não bloqueia o MVP — a feature de logo na DANFE funciona integralmente sem esta sub-issue

Referências


Classificação (Project Fields)

Priority: Medium
Compliance: Não — melhoria de DX da biblioteca, sem mandato fiscal

Follow-up

  • Templates de issue ausentes em nfe/DanfeSharp — considerar bootstrap futuramente
  • Avaliar se vale upgrade do PdfClown.NetStandard de 0.2.0-beta para versão estável (escopo separado, risco maior)
  • Se PNG support requerer ImageSharp como dependência, validar licença Split License da v3

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

origem:produtoDemanda originada de análise técnica/produto interno

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions