PerfectVector
Por Irene Kim9 min de leitura

SVG no WeasyPrint: corrija logos ausentes em PDFs

Corrija logos SVG ausentes em PDFs do WeasyPrint com uma URL base correta e tamanho CSS explícito; confira traçados vetoriais, proporções e arte no PDF salvo.

Nesta página

O WeasyPrint pode inserir um SVG em um PDF por meio de um elemento de imagem HTML. Se o logo desaparecer quando você passar HTML como string, primeiro confira a URL da imagem: um caminho relativo precisa de uma URL base. Quando o arquivo carregar, defina seu tamanho impresso em CSS e inspecione o PDF salvo. A referência atual da API do WeasyPrint documenta esse requisito de base_url.

O exemplo abaixo reproduz esse caso de imagem ausente com um logo original em forma de moldura. Ele também verifica se o PDF corrigido contém geometria vetorial de desenho no tamanho solicitado. Se você já tem um SVG, comece por esse arquivo. A vetorização só entra neste fluxo quando a arte de origem existe como pixels.

Verifique o carregamento antes de mudar a arte

Um PDF pode ser criado mesmo quando seu logo está ausente. Confira o aviso de recurso, resolva o caminho da imagem e renderize novamente o mesmo SVG antes de editar suas formas ou convertê-lo em outro formato.

Reproduza o SVG ausente com um documento pequeno

Testamos com Python 3.13.9 e WeasyPrint 70.0. Use um ambiente do projeto e instale a versão fixada:

python -m pip install "weasyprint==70.0"
python -m weasyprint --info

O WeasyPrint também precisa de bibliotecas nativas, incluindo Pango. Siga suas instruções de instalação por sistema operacional se a importação ou o comando de versão falhar. Uma biblioteca nativa ausente é um problema diferente de um logo ausente.

Crie esta estrutura de pastas:

example/
  render.py
  assets/
    logo.svg

Salve esta arte original de demonstração como assets/logo.svg. A abertura no meio oferece algo mais útil para inspecionar do que um retângulo sólido. É geometria criada manualmente, não uma conversão do PerfectVector.

<svg xmlns="http://www.w3.org/2000/svg"
     width="120" height="60" viewBox="0 0 120 60">
  <path fill="#087f8c" fill-rule="evenodd"
        d="M0 0H120V60H0Z M20 15V45H100V15Z"/>
</svg>

Coloque o seguinte em render.py:

from pathlib import Path
import logging
from weasyprint import HTML
 
logging.basicConfig(level=logging.WARNING)
root = Path(__file__).resolve().parent
 
html = """<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <style>
    @page { size: A4; margin: 20mm; }
    body { margin: 0; }
    .logo { display: block; width: 60mm; height: auto; }
  </style>
</head>
<body>
  <img class="logo" src="assets/logo.svg" alt="Frame logo">
</body>
</html>
"""
 
HTML(string=html).write_pdf(root / "missing-base.pdf")
 
HTML(
    string=html,
    base_url=root.as_uri() + "/",
).write_pdf(root / "resolved.pdf")

Execute python render.py. Em nosso primeiro PDF, a moldura estava ausente e o texto alternativo da imagem apareceu. O registro continha:

Relative URI reference without a base URI: assets/logo.svg

O segundo PDF mostrou a moldura verde-petróleo com sua abertura intacta. As duas chamadas produziram um arquivo, portanto a existência de um PDF, sozinha, não foi uma verificação útil de sucesso.

Dê aos caminhos relativos uma pasta inicial estável

assets/logo.svg identifica um arquivo em relação a outra localização. O base_url na segunda chamada fornece esse ponto inicial. root.as_uri() cria uma URI de arquivo absoluta; a barra final faz dela uma base de diretório. O logo permanece na mesma pasta assets e o conteúdo SVG não muda.

Usar Path(__file__) também mantém o exemplo vinculado à pasta do script quando você o inicia em outro diretório de trabalho. Em um notebook, use uma pasta de projeto explícita, pois __file__ normalmente não está disponível.

Ilustração de uma arte SVG em uma pasta conectada por uma seta à mesma arte em uma página de documento
Ilustração da resolução de recursos: o documento precisa de um caminho até o arquivo SVG antes de poder inserir a arte.

Há outro teste de controle útil. Salve o HTML como invoice.html ao lado de render.py e carregue o próprio arquivo:

HTML(filename=str(root / "invoice.html")).write_pdf(
    root / "from-file.pdf"
)

O WeasyPrint pode derivar uma base de um nome de arquivo ou URL de entrada. Nosso teste baseado em arquivo produziu a mesma moldura que o caso de base explícita. Uma string HTML não tem um nome de arquivo correspondente para essa inferência. Esses modos de entrada e suas regras de resolução da base são documentados no construtor HTML.

Para uma imagem hospedada atrás de um login, uma URL correta ainda pode ser insuficiente. A documentação do URL fetcher informa que o cliente HTTP padrão não fornece cookies nem autenticação. Use o mecanismo de busca de recursos aprovado para sua aplicação e teste-o no ambiente que gera o PDF. Não presuma que um logo visível em seu navegador com sessão iniciada seja acessível ao processo do PDF.

Defina o tamanho da imagem separadamente do tamanho da página PDF

O exemplo usa @page para a folha A4 e as margens, enquanto .logo define a imagem com 60 mm de largura. Sua proporção de origem 2:1 faz com que tenha 30 mm de altura com height: auto. Em nosso PDF salvo, a moldura mediu 60 × 30 mm e começou a 20 mm das bordas superior e esquerda da página.

Aqui, o desenho preenche todo o seu viewBox. Seu logo pode ter espaço vazio dentro desse retângulo, portanto uma caixa de imagem de 60 mm pode conter uma marca visivelmente mais estreita. Confira a área de desenho SVG antes de compensar com uma largura CSS arbitrariamente maior. O guia de tamanho na importação SVG explica essa distinção com mais detalhes.

Mantenha write_pdf() em seu padrão zoom=1 ao verificar dimensões físicas. A referência de saída PDF do WeasyPrint avisa que mudar zoom também escala unidades CSS físicas e tamanhos de página nomeados.

O que você vêPrimeira verificaçãoPróxima etapa
O texto alternativo substitui o logoURL da imagem e registro de recursosForneça uma URL base válida ou uma URL absoluta acessível
O logo aparece no tamanho erradoLargura CSS e proporção da origemDefina uma largura física e inspecione a área de desenho SVG
Parte da arte está ausenteLimites de origem e recurso SVG específicoReduza a um pequeno exemplo com falha e compare o PDF exportado
A renderização local funciona, mas a do servidor falhaArquivos, fontes e acesso a URLs disponíveisTeste com os recursos do processo em produção

Inspecione o conteúdo e a aparência do PDF

A documentação atual de formatos do WeasyPrint informa que imagens SVG são renderizadas como vetores na saída PDF. Isso não significa que qualquer arquivo terminado em .svg seja inteiramente vetorial: um SVG pode conter um bitmap incorporado. Verifique isso com o diagnóstico de imagens incorporadas quando o resultado ainda parecer pixelado.

Para este exemplo simples, inspecionamos os PDFs salvos com PyMuPDF 1.26.7:

Caso de entradaRegistros de desenhoImagens incorporadasMoldura visível
String HTML sem base00Ausente; o texto alternativo apareceu
String HTML com base da pasta1060 × 30 mm, abertura preservada
HTML carregado pelo nome de arquivo10Mesmo resultado da string resolvida

Esses resultados se aplicam à moldura fornecida, não a todos os recursos SVG. Um traçado composto também não significa uma única forma visível: seu subtraçado interno define a abertura.

Para inspecionar seu resolved.pdf, instale pymupdf==1.26.7 e execute:

import pymupdf
 
with pymupdf.open("resolved.pdf") as document:
    page = document[0]
    print("Drawing records:", len(page.get_drawings()))
    print("Embedded images:", len(page.get_images()))
    for drawing in page.get_drawings():
        box = drawing["rect"]
        print("Bounds in mm:", box.width * 25.4 / 72,
              box.height * 25.4 / 72)

A referência de page do PyMuPDF documenta os métodos de inspeção de desenhos e imagens. Essas contagens são diagnósticos, não um certificado de fidelidade. Abra também o PDF: confira a abertura, as cores, as proporções e qualquer texto no tamanho real de entrega. Inspecione arte complexa recurso por recurso e repita as verificações ao atualizar o renderizador.

Quando preparar um novo SVG primeiro

Quando o único logo disponível é um PNG ou JPG, o vetorizador de logos do PerfectVector pode preparar um candidato SVG antes de você inseri-lo no documento HTML. Inspecione os contornos, as pequenas aberturas e as letras em um editor e teste o SVG no mesmo fluxo WeasyPrint. O guia de vetorização de imagens explica o que muda quando pixels viram traçados.

Mantenha um SVG original editável quando ele existir. Corrija sua referência de arquivo ou seu layout em vez de traçá-lo novamente. Fotografias podem continuar como imagens raster, e letras exatas de uma marca podem exigir a fonte original ou um redesenho manual. A vetorização não corrige arquivos ausentes no servidor, autenticação nem recursos de renderização incompatíveis.

Se você só precisa converter um SVG em sua própria página PDF, o fluxo de exportação CairoSVG aborda essa tarefa menor. O WeasyPrint se encaixa no caso do documento HTML, em que a arte divide uma página com outros conteúdos.

Perguntas frequentes

Por que o WeasyPrint cria um PDF sem meu logo SVG? Uma falha no carregamento da imagem pode deixar o restante do documento renderizável. Confira o registro de recursos e a URL da imagem. No teste fornecido, uma string HTML com caminho relativo de imagem precisava de uma URL base explícita.

Preciso converter o SVG em PNG primeiro? Não. O WeasyPrint aceita imagens SVG. Mantenha a arte vetorial compatível como SVG quando essa for a saída pretendida e confira o PDF salvo. Uma exportação raster é uma alternativa quando você escolhe deliberadamente a aparência em vez da geometria vetorial.

base_url muda o tamanho impresso do logo? Não. Ele fornece a base para resolver URLs relativas de recursos. Defina o tamanho de inserção da imagem com CSS e confira as dimensões e o viewBox do SVG separadamente.

Fontes

  1. Referência da API do WeasyPrint — Documenta entradas HTML, URLs base, saída SVG e comportamento do zoom PDF.
  2. WeasyPrint — Primeiros passos — Aborda instalação e busca de recursos, incluindo limites de autenticação.
  3. PyMuPDF — Referência de Page — Documenta os métodos de inspeção de desenhos e imagens incorporadas usados no exemplo.

Só tem um logo raster? Prepare um SVG com o PerfectVector, inspecione suas formas e letras, insira-o no HTML e verifique sua aparência e seu tamanho físico no PDF salvo.

Mais do blog

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