PerfectVector
Por Irene Kim9 min de leitura

SVG no ReportLab: logos nítidos em PDFs gerados

Insira logos SVG em PDFs do ReportLab com svglib, preserve suas proporções e confira traçados vetoriais, tamanho correto e detalhes ausentes no arquivo final.

Nesta página

Use svglib.svg2rlg() para ler um SVG como um Drawing do ReportLab e insira esse desenho com renderPDF.draw(). Dê a ele uma caixa com medidas definidas na página e use um único fator de escala nos dois eixos. Isso mantém uma geometria de logo adequada como instruções de desenho PDF, em vez de inserir uma captura de tela em bitmap.

Para uma exportação independente sem layout de documento, o fluxo de dimensionamento do CairoSVG compara pixels PNG, dimensões de página PDF e DPI.

O teste útil é o PDF final: o emblema manteve suas proporções, cores e pequenas aberturas no tamanho de que seu documento precisa? Uma chamada Python bem-sucedida não responde a essas perguntas. O exemplo abaixo insere o mesmo emblema original duas vezes e confere o arquivo produzido.

Se você já tem o logo como arte vetorial editável, comece por ela. Se resta apenas um PNG ou JPG, recupere um mestre vetorial antes de montar o documento. Fotos e gráficos numéricos exigem outra decisão sobre o material de origem.

Importe a arte como desenho

O fluxo documentado do svglib converte SVG em objetos de desenho do ReportLab. O guia de gráficos do ReportLab explica que esses desenhos podem ser renderizados em um canvas ou usados como elementos de fluxo do Platypus. Neste exemplo, um canvas dá a cada inserção uma posição e um tamanho explícitos.

Executamos o exemplo com Python 3.12, svglib 2.2.0 e ReportLab 4.4.9. Instale os dois pacotes com versões fixadas no ambiente do seu projeto:

python -m pip install "svglib==2.2.0" "reportlab==4.4.9"

Salve este pequeno emblema como logo.svg. Ele contém três traçados com preenchimentos sólidos e nenhuma imagem vinculada, fonte ou efeito. É uma arte feita manualmente para esta demonstração, não um resultado de conversão do PerfectVector.

<svg xmlns="http://www.w3.org/2000/svg"
     width="240" height="120" viewBox="0 0 240 120">
  <path fill="#1c625e" d="M0 120 L60 0 L120 120 Z"/>
  <path fill="#e5a340" d="M96 120 L156 24 L216 120 Z"/>
  <path fill="#163451" d="M228 12 L240 12 L240 108 L228 108 Z"/>
</svg>

O viewBox do SVG descreve seu retângulo interno de coordenadas. Os valores de width e height do desenho importado informam as dimensões que você deve usar para posicioná-lo no PDF. Leia-os, em vez de supor que um pixel SVG equivale a um ponto PDF.

Para este arquivo, o svglib 2.2.0 retornou 180 × 90 pontos. Sua documentação atual de unidades mapeia um pixel CSS para 0.75 ponto PDF. Exemplos mais antigos podem usar outras suposições; por isso, confira as dimensões ao atualizar um fluxo existente.

Ajuste o logo sem esticá-lo

Salve o seguinte como place_logo.py ao lado do SVG e execute python place_logo.py. Todas as posições de página e dimensões de caixa aqui estão em pontos PDF. Há 72 pontos em uma polegada; a origem padrão do canvas fica no canto inferior esquerdo, conforme descrito no guia de canvas do ReportLab.

from reportlab.graphics import renderPDF
from reportlab.pdfgen import canvas
from svglib.svglib import svg2rlg
 
 
def draw_svg_in_box(pdf, drawing, x, y, box_w, box_h):
    if drawing.width <= 0 or drawing.height <= 0:
        raise ValueError("The SVG needs positive dimensions")
    factor = min(box_w / drawing.width, box_h / drawing.height)
    pdf.saveState()
    pdf.translate(x, y)
    pdf.scale(factor, factor)
    renderPDF.draw(drawing, pdf, 0, 0)
    pdf.restoreState()
 
 
drawing = svg2rlg("logo.svg")
if drawing is None:
    raise ValueError("SVG could not be loaded")
 
pdf = canvas.Canvas("logo.pdf", pagesize=(640, 360))
draw_svg_in_box(pdf, drawing, 40, 154, 144, 72)
draw_svg_in_box(pdf, drawing, 302, 126, 288, 144)
pdf.save()

min() escolhe a dimensão limitante, de modo que o desenho caiba dentro da caixa. Usar o mesmo fator para X e Y preserva as proporções. Essa função ancora o desenho no canto inferior esquerdo da caixa; o espaço não usado fica acima ou à direita. Centralize-o separadamente se o layout exigir.

A transformação do canvas é temporária. restoreState() impede que a escala do logo altere textos ou elementos posteriores da página, e o desenho original continua disponível para a segunda inserção.

No teste, os dois fatores foram 0.8 e 1.6, produzindo artes de 144 × 72 pt e 288 × 144 pt. A prévia acrescenta rótulos e um fundo às mesmas duas inserções para facilitar a comparação de seus tamanhos.

O mesmo emblema verde e dourado inserido com 144 por 72 pontos e 288 por 144 pontos em um PDF renderizado
Captura do PDF de teste renderizado. O logo consiste em três traçados originais desenhados em dois tamanhos. A imagem da web é uma prévia raster; a inspeção do PDF confirmou traçados de desenho e nenhuma imagem incorporada.

Em um documento Platypus, um desenho pode entrar na sequência de conteúdo como elemento de fluxo. Depois de escalar seu conteúdo com drawing.scale(factor, factor), atualize drawing.width e drawing.height pelo mesmo fator para que o layout use a nova área ocupada. Trabalhe com um desenho novo ao aplicar tamanhos diferentes. O exemplo de canvas acima evita alterar o próprio desenho.

Confira a geometria e a aparência separadamente

Inspecionamos o fluxo de conteúdo do PDF de teste com pypdf 6.10.0. Ele continha seis operações de início de traçado, correspondentes aos três traçados do emblema desenhados duas vezes, e zero imagens de página. Também renderizamos a página inteira com Poppler e inspecionamos os dois emblemas. As formas, a sobreposição, a barra vertical e as proporções corresponderam às inserções pretendidas.

Essas observações se aplicam a este exemplo simples de teste. Contar traçados, por si só, não comprova que todos os recursos de outro SVG foram renderizados corretamente. Da mesma forma, aplicar zoom a um PDF na tela não permite concluir se ele contém instruções vetoriais ou um bitmap grande.

Para seu documento:

  1. Compare o PDF final com o SVG em um navegador ou editor. Procure detalhes ausentes, preenchimentos alterados, recortes e áreas brancas inesperadas.
  2. Confira o emblema no tamanho pretendido no documento, em que espaços estreitos e contornos finos precisam continuar legíveis.
  3. Inspecione os objetos de imagem do PDF se o fluxo exige arte vetorial. Considere as fotos intencionais em outros lugares da página.
  4. Mantenha o mestre SVG junto do código de geração do documento. Confira novamente o PDF após alterar a arte ou suas dependências de renderização.

Um SVG pode conter uma imagem raster. Ler esse invólucro não recupera traçados de seus pixels. O diagnóstico de imagens incorporadas ajuda a distinguir um mestre vetorial de um SVG que ainda contém um bitmap.

Trate os recursos que o importador não consegue reproduzir

As limitações atuais do svglib incluem máscaras e elementos foreignObject incompatíveis, regras @import de folhas de estilo ignoradas e restrições de CSS e recorte. Uma prévia no navegador, portanto, não substitui o teste do importador PDF.

Mantenha uma cópia do mestre antes de simplificá-lo. Quando um logo depende de um efeito incompatível, considere reconstruir essa parte como geometria comum ou usar outra opção de exportação que você possa verificar. Preserve o raster original quando a aparência fotográfica importa mais que a edição dos traçados. Uma imagem achatada pode preservar a aparência, mas muda o requisito vetorial.

Para letras, escolha deliberadamente entre texto do documento e arte em contornos. Manter as palavras como texto permite edição e busca, mas exige que a fonte pretendida esteja disponível no fluxo do documento. Converter as letras aprovadas do logo em contornos preserva sua forma, abrindo mão da edição normal de texto. Nosso emblema composto apenas por traçados não testa o tratamento de fontes; use uma amostra real de sua tipografia antes de confiar no mesmo fluxo.

Se você monta o documento em um sistema de composição tipográfica em vez de Python, o fluxo de SVG no LaTeX explica uma opção separada para gráficos e rótulos.

Recupere um logo disponível apenas em raster antes de inseri-lo no PDF

Um PNG antigo em um modelo de fatura é um candidato razoável à recuperação vetorial quando o arquivo original do logo está ausente. Com o vetorizador de logos do PerfectVector, visualize a arte raster como SVG, inspecione os contornos e aberturas e baixe uma versão candidata para seu fluxo de documentos.

Confira as letras pequenas e as bordas antes de importá-lo. Redesenhe ou recomponha os elementos que exigem tipografia exata e remova geometrias de fundo indesejadas em um editor. O guia de vetorização de logos aborda essa decisão de transformar a imagem original em um arquivo mestre em mais detalhes.

Depois, execute a importação real do ReportLab e as verificações do PDF acima. Uma boa vetorização ainda precisa passar pelo importador e caber no documento. O PerfectVector fornece os traçados da arte; ele não escolhe as coordenadas do ReportLab, não registra fontes do documento nem verifica o PDF resultante. Para gráficos, regenere a partir dos dados e do código-fonte de plotagem, em vez de vetorizar seus rótulos ou valores plotados.

Perguntas frequentes

Posso passar um SVG ao ReportLab como uma imagem bitmap comum? Use svglib para produzir um Drawing e renderize-o com renderPDF neste fluxo vetorial. Converter primeiro o SVG para PNG produz uma inserção raster.

Por que meu SVG importado é menor que o de um exemplo mais antigo? O svglib 2.2.0 testado mapeia pixels CSS para pontos PDF com um fator de 0.75. Leia as dimensões retornadas do desenho e ajuste-as a uma caixa explícita, em vez de depender de suposições antigas de conversão entre pixels e pontos.

Isso preserva todos os efeitos de SVG? Não. O importador tem limites de recursos documentados, incluindo máscaras e foreignObject. Compare o PDF exportado com a arte pretendida, mesmo quando o script termina sem erro.

Devo vetorizar uma captura de tela de um gráfico? Regenere um gráfico a partir de seus dados e do código-fonte de plotagem sempre que possível. Reserve a vetorização de logos para artes decorativas adequadas cujo original editável esteja ausente.

Fontes

  1. svglib — documentação do pacote e das unidades — Conversão de SVG para Drawing, instalação e dimensionamento em pontos PDF.
  2. ReportLab — gráficos — Objetos Drawing, renderização PDF e uso como elementos de fluxo do Platypus.
  3. ReportLab — gráficos e texto com pdfgen — Coordenadas do canvas, pontos e transformações.
  4. svglib — limitações conhecidas — Restrições de importação que exigem conferir o PDF final.

Mantenha o original editável quando você o tiver. Se resta apenas uma arte raster do logo, prepare uma versão candidata do logo em SVG, inspecione seus traçados, insira-o no tamanho necessário e confira o PDF final.

Mais do blog

Recomece com um SVG mais limpo
e fácil de editar