Imágenes SVG en WeasyPrint: corrige logotipos ausentes en PDF
Corrige logotipos SVG ausentes en PDF de WeasyPrint con una URL base correcta y tamaños CSS explícitos, y comprueba trazados vectoriales, proporciones e ilustración en el PDF guardado.
En esta página
WeasyPrint puede colocar un SVG en un PDF mediante un elemento de imagen HTML. Si el logotipo desaparece al pasar HTML como cadena, comprueba primero la URL de la imagen: una ruta relativa necesita una URL base. Una vez cargado el archivo, establece su tamaño de impresión en CSS e inspecciona el PDF guardado. La referencia actual de la API de WeasyPrint documenta este requisito de base_url.
El ejemplo siguiente reproduce ese caso de imagen ausente con un logotipo original en forma de marco. También comprueba que el PDF reparado contenga geometría de dibujo vectorial al tamaño solicitado. Si ya tienes un SVG, empieza con ese archivo. La vectorización solo entra en este flujo cuando la ilustración original existe como píxeles.
Comprueba la carga antes de cambiar la ilustración
Se puede crear un PDF aunque falte su logotipo. Comprueba la advertencia del recurso, resuelve la ruta de imagen y vuelve a renderizar el mismo SVG antes de editar sus formas o convertirlo a otro formato.
Reproduce el SVG ausente con un documento pequeño
Probamos con Python 3.13.9 y WeasyPrint 70.0. Usa un entorno de proyecto e instala la versión fijada:
python -m pip install "weasyprint==70.0"
python -m weasyprint --infoWeasyPrint también necesita bibliotecas nativas, incluido Pango. Sigue sus instrucciones de instalación según el sistema operativo si fallan la importación o el comando de versión. Una biblioteca nativa ausente es un problema diferente de un logotipo ausente.
Crea esta estructura de carpetas:
example/
render.py
assets/
logo.svgGuarda esta ilustración original de demostración como assets/logo.svg. La abertura central permite inspeccionar algo más útil que un rectángulo sólido. Es geometría creada manualmente, no una conversión de 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>Coloca lo siguiente en 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")Ejecuta python render.py. En nuestro primer PDF, el marco no aparecía y se mostraba el texto alternativo de la imagen. El registro contenía:
Relative URI reference without a base URI: assets/logo.svgEl segundo PDF mostró el marco verde azulado con su abertura intacta. Ambas llamadas produjeron un archivo, por lo que la existencia de un PDF no era por sí sola una comprobación útil de éxito.
Da a las rutas relativas una carpeta inicial estable
assets/logo.svg identifica un archivo relativo a otra ubicación. El base_url de la segunda llamada proporciona ese punto de partida. root.as_uri() crea una URI de archivo absoluta; la barra final la convierte en una base de directorio. El logotipo permanece en la misma carpeta assets y el contenido SVG no cambia.
Usar Path(__file__) también mantiene el ejemplo vinculado a la carpeta del script cuando lo ejecutas desde otro directorio de trabajo. En un cuaderno, usa una carpeta explícita del proyecto, ya que __file__ normalmente no está disponible.

Hay otra prueba de control útil. Guarda el HTML como invoice.html junto a render.py y carga el propio archivo:
HTML(filename=str(root / "invoice.html")).write_pdf(
root / "from-file.pdf"
)WeasyPrint puede deducir una base a partir del nombre de archivo o URL de entrada. Nuestra prueba basada en archivo produjo el mismo marco que el caso con base explícita. Una cadena HTML no tiene un nombre de archivo correspondiente del que deducirlo. Estos modos de entrada y sus reglas de resolución de base se documentan en el constructor HTML.
Para una imagen alojada detrás de un inicio de sesión, una URL correcta puede seguir siendo insuficiente. La documentación del recuperador de URL indica que el cliente HTTP predeterminado no proporciona cookies ni autenticación. Usa el mecanismo de obtención de recursos aprobado de tu aplicación y pruébalo en el entorno que genera el PDF. No supongas que un logotipo visible en tu navegador con sesión iniciada sea accesible para el proceso PDF.
Establece el tamaño de imagen por separado del tamaño de página PDF
El ejemplo usa @page para la hoja A4 y los márgenes, mientras que .logo establece una anchura de imagen de 60 mm. Su proporción original 2:1 le da 30 mm de altura con height: auto. En nuestro PDF guardado, el marco medía 60 × 30 mm y empezaba a 20 mm de los bordes superior e izquierdo de la página.
Aquí el dibujo ocupa todo su viewBox. Tu logotipo puede tener espacio vacío dentro de ese rectángulo, así que una caja de imagen de 60 mm puede contener una marca visiblemente más estrecha. Comprueba el lienzo SVG antes de compensarlo con una anchura CSS mayor arbitraria. La guía de tamaño de importación SVG explica esta distinción con más detalle.
Mantén write_pdf() con su valor predeterminado zoom=1 al comprobar dimensiones físicas. La referencia de salida PDF de WeasyPrint advierte que cambiar zoom también escala las unidades CSS físicas y los tamaños de página con nombre.
| Qué ves | Primera comprobación | Siguiente paso |
|---|---|---|
| El texto alternativo sustituye al logotipo | URL de imagen y registro de recursos | Proporciona una URL base válida o una URL absoluta accesible |
| El logotipo aparece con tamaño incorrecto | Anchura CSS y relación de aspecto original | Establece una anchura física e inspecciona el lienzo SVG |
| Falta parte de la ilustración | Límites originales y función SVG concreta | Reduce a un ejemplo pequeño que falle y compara el PDF exportado |
| El renderizado local funciona, pero el del servidor falla | Archivos, fuentes y acceso URL disponibles | Prueba con los recursos del proceso desplegado |
Inspecciona el contenido y el aspecto del PDF
La documentación actual de formatos de WeasyPrint indica que las imágenes SVG se renderizan como vectores en la salida PDF. Eso no significa que cualquier archivo terminado en .svg sea una ilustración completamente vectorial: un SVG puede contener un mapa de bits incrustado. Compruébalo con el diagnóstico de imágenes incrustadas cuando el resultado siga viéndose pixelado.
Para este ejemplo sencillo, inspeccionamos los PDF guardados con PyMuPDF 1.26.7:
| Caso de entrada | Registros de dibujo | Imágenes incrustadas | Marco visible |
|---|---|---|---|
| Cadena HTML sin base | 0 | 0 | Ausente; apareció el texto alternativo |
| Cadena HTML con base de carpeta | 1 | 0 | 60 × 30 mm, abertura conservada |
| HTML cargado por nombre de archivo | 1 | 0 | Mismo resultado que la cadena resuelta |
Estos resultados se aplican al marco proporcionado, no a todas las funciones SVG. Un trazado compuesto tampoco significa una forma visible única: su subtrazado interior define la abertura.
Para inspeccionar tu resolved.pdf, instala pymupdf==1.26.7 y ejecuta:
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)La referencia de Page de PyMuPDF documenta los métodos de inspección de dibujos e imágenes. Estos recuentos son diagnósticos, no un certificado de fidelidad. Abre también el PDF: comprueba la abertura, los colores, las proporciones y las letras al tamaño real de entrega. Inspecciona las ilustraciones complejas elemento por elemento y repite las comprobaciones al actualizar el renderizador.
Cuándo conviene preparar primero un nuevo SVG
Cuando el único logotipo disponible es un PNG o JPG, el vectorizador de logotipos de PerfectVector puede preparar una primera versión SVG antes de colocarla en el documento HTML. Inspecciona los contornos, las aberturas pequeñas y las letras en un editor y prueba el SVG mediante el mismo proceso WeasyPrint. La guía de vectorización de imágenes explica qué cambia cuando los píxeles se convierten en trazados.
Conserva un SVG editable original cuando exista. Corrige su referencia de archivo o distribución en lugar de volver a vectorizarlo. Las fotografías pueden seguir siendo imágenes rasterizadas y las letras de marca exactas pueden necesitar la fuente original o un redibujo manual. La vectorización no repara archivos de servidor ausentes, autenticación ni funciones de renderizado incompatibles.
Si solo necesitas convertir un SVG en su propia página PDF, el flujo de exportación de CairoSVG cubre esa tarea más pequeña. WeasyPrint encaja en el caso de documentos HTML, donde la ilustración comparte página con otro contenido.
Preguntas frecuentes
¿Por qué WeasyPrint crea un PDF sin mi logotipo SVG? Un fallo de carga de imagen puede permitir que se renderice el resto del documento. Comprueba el registro de recursos y la URL de imagen. En la prueba proporcionada, una cadena HTML con ruta de imagen relativa necesitó una URL base explícita.
¿Tengo que convertir primero el SVG en PNG? No. WeasyPrint acepta imágenes SVG. Conserva las ilustraciones vectoriales compatibles como SVG cuando esa sea la salida prevista y comprueba el PDF guardado. Una exportación rasterizada es una alternativa cuando eliges deliberadamente el aspecto sobre la geometría vectorial.
¿base_url cambia el tamaño impreso del logotipo? No. Proporciona la base para resolver URL de recursos relativas. Establece el tamaño de colocación de la imagen con CSS y comprueba por separado las dimensiones y el viewBox del SVG.
Fuentes
- Referencia de API de WeasyPrint — Documenta entradas HTML, URL base, salida SVG y comportamiento del zoom PDF.
- Primeros pasos de WeasyPrint — Cubre instalación y obtención de recursos, incluidos los límites de autenticación.
- Referencia de Page de PyMuPDF — Documenta los métodos de inspección de dibujos e imágenes incrustadas usados en el ejemplo.
¿Solo tienes un logotipo rasterizado? Prepara un SVG con PerfectVector, inspecciona sus formas y letras, colócalo en tu HTML y verifica su aspecto y tamaño físico en el PDF guardado.
Más del blog

Imágenes SVG en Graphviz: conserva portátiles los gráficos de nodos
Añade un gráfico SVG a un nodo Graphviz, revisa su referencia de imagen y prueba un paquete completo frente a un diagrama movido y una copia de entrega autónoma.

SVG en Matplotlib: conserva el gráfico y el logotipo como trazados
Exporta tu gráfico de Matplotlib como SVG, compón trazados de logotipo separados con svgutils y comprueba píxeles incrustados, colocación y cambios de fuente en el archivo entregado.