PerfectVector
Por Irene Kim9 min de lectura

SVG en ReportLab: conserva trazados de logotipo nítidos en PDF generados

Coloca logotipos SVG en PDF de ReportLab con svglib, conserva sus proporciones y comprueba trazados vectoriales, tamaño correcto y detalles ausentes en el archivo final.

En esta página

Usa svglib.svg2rlg() para leer un SVG como un Drawing de ReportLab y coloca después ese dibujo con renderPDF.draw(). Dale un cuadro medido en la página y utiliza un único factor de escala para ambos ejes. Así conservas la geometría adecuada del logotipo como instrucciones de dibujo PDF en lugar de insertar una captura de mapa de bits.

Para una exportación independiente sin composición de documentos, el flujo de tamaños de CairoSVG compara píxeles PNG, dimensiones de página PDF y DPI.

La prueba útil es el PDF terminado: ¿el emblema conservó sus proporciones, colores y aberturas pequeñas al tamaño que necesita tu documento? Una llamada Python correcta no responde a esas preguntas. El ejemplo siguiente coloca dos veces el mismo emblema original y comprueba el archivo que produce.

Si ya tienes el logotipo como ilustración vectorial editable, empieza por él. Si solo queda un PNG o JPG, recupera un maestro vectorial antes de construir el documento. Las fotos y los gráficos numéricos necesitan otra decisión sobre el original.

Importa la ilustración como dibujo

El flujo documentado de svglib convierte SVG en objetos de dibujo de ReportLab. La guía de gráficos de ReportLab explica que estos dibujos pueden renderizarse sobre un lienzo o utilizarse como elementos de flujo de Platypus. Para este ejemplo, un lienzo da a cada colocación una posición y tamaño explícitos.

Ejecutamos el ejemplo con Python 3.12, svglib 2.2.0 y ReportLab 4.4.9. Instala los dos paquetes con versiones fijadas en tu entorno de proyecto:

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

Guarda este pequeño emblema como logo.svg. Contiene tres trazados con rellenos sólidos y sin imágenes enlazadas, fuentes ni efectos. Es una ilustración creada a mano para esta demostración, no un resultado de conversión de 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>

El viewBox del SVG describe su rectángulo interno de coordenadas. El width y height del dibujo importado indican las dimensiones que debes utilizar para colocarlo en PDF. Léelas en lugar de suponer que un píxel SVG equivale a un punto PDF.

Para este archivo, svglib 2.2.0 devolvió 180 × 90 puntos. Su documentación actual de unidades asigna 0.75 puntos PDF a un píxel CSS. Los ejemplos antiguos pueden utilizar otras suposiciones, así que comprueba las dimensiones al actualizar un proceso existente.

Ajusta el logotipo sin estirarlo

Guarda lo siguiente como place_logo.py junto al SVG y ejecuta python place_logo.py. Todas las posiciones de página y dimensiones de cuadros de aquí son puntos PDF. Una pulgada tiene 72 puntos; el origen predeterminado del lienzo está abajo a la izquierda, como describe la guía del lienzo de 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() elige la dimensión limitante para que el dibujo quepa dentro del cuadro. Utilizar el mismo factor para X e Y conserva las proporciones. Esta función ancla el dibujo en la esquina inferior izquierda del cuadro; el espacio no utilizado queda arriba o a la derecha. Céntralo por separado si lo requiere tu composición.

La transformación del lienzo es temporal. restoreState() evita que la escala del logotipo cambie el texto o elementos de página posteriores, y el dibujo original sigue disponible para la segunda colocación.

En la prueba, los dos factores fueron 0.8 y 1.6, produciendo ilustraciones de 144 × 72 pt y 288 × 144 pt. La vista previa añade etiquetas y un fondo a las mismas dos colocaciones para facilitar comparar sus tamaños.

El mismo emblema verde y dorado colocado a 144 por 72 puntos y a 288 por 144 puntos en un PDF renderizado
Captura del PDF de prueba renderizado. El logotipo consta de tres trazados originales dibujados a dos tamaños. La imagen web es una vista previa raster; la inspección del PDF confirmó trazados de dibujo y ninguna imagen incrustada.

Para un documento Platypus, un dibujo puede incorporarse al contenido como elemento de flujo. Después de escalar su contenido con drawing.scale(factor, factor), actualiza drawing.width y drawing.height con el mismo factor para que la composición utilice el nuevo espacio ocupado. Trabaja desde un dibujo nuevo al aplicar tamaños diferentes. El ejemplo de lienzo anterior evita modificar el propio dibujo.

Comprueba la geometría y la apariencia por separado

Inspeccionamos el flujo de contenido del PDF de prueba con pypdf 6.10.0. Contenía seis operaciones de inicio de trazado, correspondientes a los tres trazados del emblema dibujados dos veces, y cero imágenes de página. También renderizamos toda la página con Poppler e inspeccionamos los dos emblemas. Las formas, la superposición, la barra vertical y las proporciones coincidían con las colocaciones previstas.

Estas observaciones se aplican a este ejemplo sencillo. Contar trazados por sí solo no demuestra que todos los elementos de otro SVG se hayan renderizado correctamente. Del mismo modo, ampliar un PDF en pantalla no permite determinar concluyentemente si contiene instrucciones vectoriales o un mapa de bits grande.

Para tu propio documento:

  1. Compara el PDF terminado con el SVG en un navegador o editor. Busca detalles ausentes, rellenos cambiados, recortes y áreas blancas inesperadas.
  2. Comprueba el emblema al tamaño de documento previsto, donde los huecos estrechos y los trazos finos deben seguir legibles.
  3. Inspecciona los objetos de imagen PDF si el flujo requiere ilustración vectorial. Ten en cuenta las fotografías intencionadas de otras partes de la página.
  4. Conserva el maestro SVG junto al código de generación del documento. Vuelve a comprobar el PDF después de cambiar la ilustración o sus dependencias de renderizado.

Un SVG puede contener una imagen raster. Leer ese contenedor no recupera trazados de sus píxeles. El diagnóstico de imagen incrustada ayuda a distinguir un maestro vectorial de un SVG que sigue llevando un mapa de bits.

Gestiona las funciones que el importador no puede reproducir

Las limitaciones actuales de svglib incluyen máscaras y elementos foreignObject incompatibles, reglas @import de hojas de estilo ignoradas y restricciones de CSS y recorte. Por tanto, una vista previa de navegador no sustituye a probar el importador PDF.

Conserva una copia del maestro antes de simplificarlo. Cuando un logotipo dependa de un efecto incompatible, considera reconstruir esa parte como geometría ordinaria o utilizar otro método de exportación que puedas verificar. Conserva el raster original cuando el aspecto fotográfico importe más que editar trazados. Una imagen aplanada puede conservar la apariencia, pero cambia el requisito vectorial.

Para las letras, elige deliberadamente entre texto de documento e ilustración convertida en contornos. Mantener las palabras como texto permite editar y buscar, pero requiere que la fuente prevista esté disponible en el flujo de documentos. Convertir en contornos las letras aprobadas del logotipo conserva su forma a costa de renunciar a la edición normal de texto. Nuestro emblema de solo trazados no prueba la gestión de fuentes; utiliza una muestra real de tu tipografía antes de depender del mismo proceso.

Si ensamblas el documento en un sistema de composición tipográfica en lugar de Python, el flujo SVG en LaTeX explica un método separado de gráficos y etiquetas.

Recupera un logotipo raster antes de colocarlo en PDF

Un PNG antiguo de una plantilla de factura es un candidato razonable para recuperar vectores cuando falta el archivo original del logotipo. Con el vectorizador de logotipos de PerfectVector, previsualiza la ilustración raster como SVG, inspecciona los contornos y aberturas y descarga un candidato para tu proceso de documentos.

Comprueba las letras pequeñas y los bordes antes de importarlo. Redibuja o vuelve a componer los elementos que necesiten tipografía exacta y elimina en un editor la geometría de fondo no deseada. La guía de vectorización de logotipos explica con más detalle esa decisión del original al maestro.

Después ejecuta la importación real de ReportLab y las comprobaciones PDF anteriores. Una buena vectorización todavía debe sobrevivir al importador y encajar en el documento. PerfectVector proporciona trazados de ilustración; no elige coordenadas de ReportLab, no registra fuentes de documento ni verifica el PDF resultante. Para gráficos, regenera desde los datos y el código original en lugar de vectorizar sus etiquetas o valores representados.

Preguntas frecuentes

¿Puedo pasar un SVG a ReportLab como una imagen de mapa de bits ordinaria? Utiliza svglib para producir un Drawing y renderízalo con renderPDF para este flujo vectorial. Convertir primero el SVG a PNG produce en cambio una inserción raster.

¿Por qué mi SVG importado es más pequeño que en un ejemplo antiguo? El svglib 2.2.0 probado asigna los píxeles CSS a puntos PDF con un factor de 0.75. Lee las dimensiones del dibujo devuelto y ajústalas a un cuadro explícito en lugar de depender de suposiciones antiguas de píxeles a puntos.

¿Esto conserva todos los efectos SVG? No. El importador tiene límites documentados de funciones, incluidas máscaras y foreignObject. Compara el PDF exportado con la ilustración prevista, aunque el script termine sin errores.

¿Debería vectorizar una captura de un gráfico? Regenera un gráfico a partir de sus datos y código original siempre que sea posible. Reserva la vectorización de logotipos para ilustraciones decorativas adecuadas cuyo original editable falte.

Fuentes

  1. svglib — Documentación del paquete y unidades — Conversión de SVG a Drawing, instalación y tamaños en puntos PDF.
  2. ReportLab — Gráficos — Objetos Drawing, renderizado PDF y uso como elementos de flujo de Platypus.
  3. ReportLab — Gráficos y texto con pdfgen — Coordenadas del lienzo, puntos y transformaciones.
  4. svglib — Limitaciones conocidas — Restricciones de importación que requieren comprobar el PDF terminado.

Conserva el original editable cuando lo tengas. Si solo queda una ilustración raster del logotipo, prepara un SVG candidato del logotipo, inspecciona sus trazados, colócalo después al tamaño requerido y comprueba el PDF terminado.

Más del blog

Empieza con un SVG más limpio
y fácil de editar