> [Site index](https://perfectvector.com/llms.txt) — available pages and descriptions.

# ReportLab SVG: Keep Logo Paths Sharp in Generated PDFs

> Place SVG logos in ReportLab PDFs with svglib, preserve their proportions, and check the finished file for vector paths, correct size, and missing details.

Source: https://perfectvector.com/blog/reportlab-svg

Language: en
Author: Irene Kim
Published: 2026-09-17T08:00:00+09:00

Use `svglib.svg2rlg()` to read an SVG into a ReportLab `Drawing`, then place that drawing with `renderPDF.draw()`. Give it a measured box on the page and use one scale factor for both axes. This keeps suitable logo geometry as PDF drawing instructions instead of inserting a bitmap screenshot.

For a standalone export with no document layout, the [CairoSVG sizing workflow](https://perfectvector.com/blog/cairosvg-output-size) compares PNG pixels, PDF page dimensions, and DPI.

For artwork added to an existing multipage document, [merge an SVG watermark into the original PDF pages](https://perfectvector.com/blog/svg-watermark-existing-pdf). That workflow handles page crop origins, rotation, and overlay order rather than composing a new document.

The useful test is the finished PDF: did the emblem keep its proportions, colors, and small openings at the size your document needs? A successful Python call does not answer those questions. The example below places the same original emblem twice and checks the file it produces.

If you already have the logo as editable vector artwork, start there. If only a PNG or JPG survives, recover a vector master before building the document. Photos and numerical charts need a different source decision.

## Import the artwork as a drawing

[svglib's documented workflow](https://pypi.org/project/svglib/) converts SVG into ReportLab drawing objects. ReportLab's [graphics guide](https://docs.reportlab.com/reportlab/userguide/ch11_graphics/) explains that these drawings can be rendered onto a canvas or used as Platypus flowables. For this example, a canvas gives each placement an explicit position and size.

We ran the example with Python 3.12, svglib 2.2.0, and ReportLab 4.4.9. Install the two pinned packages in your project environment:

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

Save this small emblem as `logo.svg`. It contains three paths with solid fills and no linked images, fonts, or effects. It is hand-authored artwork for this demonstration, not a PerfectVector conversion result.

```xml
<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>
```

The SVG's `viewBox` describes its internal coordinate rectangle. The imported drawing's `width` and `height` tell you the dimensions you should use for PDF placement. Read them rather than assuming that an SVG pixel equals a PDF point.

For this file, svglib 2.2.0 returned **180 × 90 points**. Its current [units documentation](https://pypi.org/project/svglib/#units-and-output-sizes) maps a CSS pixel to 0.75 PDF points. Older examples may use different assumptions, so check dimensions when upgrading an existing pipeline.

## Fit the logo without stretching it

Save the following as `place_logo.py` beside the SVG and run `python place_logo.py`. All page positions and box dimensions here are PDF points. There are 72 points in an inch; the default canvas origin is at the lower left, as described in [ReportLab's canvas guide](https://docs.reportlab.com/reportlab/userguide/ch2_graphics/).

```python
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()` chooses the limiting dimension, so the drawing fits inside the box. Using the same factor for X and Y preserves proportions. This function anchors the drawing at the box's lower-left corner; unused space stays above or to the right. Center it separately if your layout requires that.

The canvas transformation is temporary. `restoreState()` prevents the logo's scaling from changing later text or page elements, and the original drawing remains available for the second placement.

In the test, the two factors were **0.8** and **1.6**, producing **144 × 72 pt** and **288 × 144 pt** artwork. The preview adds labels and a background to the same two placements so their sizes are easy to compare.

![The same green and gold emblem placed at 144 by 72 points and 288 by 144 points in a rendered PDF](https://perfectvector.com/blog/reportlab-svg/pdf-placements.webp)

*Capture of the rendered test PDF. The logo consists of three original paths drawn at two sizes. The web image is a raster preview; inspection of the PDF confirmed drawing paths and no embedded images.*

For a Platypus document, a drawing can join the story as a flowable. After scaling its contents with `drawing.scale(factor, factor)`, update `drawing.width` and `drawing.height` by the same factor so layout uses the new footprint. Work from a fresh drawing when applying different sizes. The canvas example above avoids changing the drawing itself.

## Check geometry and appearance separately

We inspected the test PDF's content stream with pypdf 6.10.0. It contained six path-start operations, corresponding to the three emblem paths drawn twice, and zero page images. We also rendered the entire page with Poppler and inspected the two emblems. The shapes, overlap, vertical bar, and proportions matched the intended placements.

Those observations apply to this simple fixture. Counting paths alone does not prove that every feature of another SVG rendered correctly. Likewise, zooming a PDF on screen cannot conclusively tell you whether it contains vector instructions or a large bitmap.

For your own document:

1. Compare the finished PDF against the SVG in a browser or editor. Look for missing details, changed fills, clipping, and unexpected white areas.
2. Check the emblem at the intended document size, where narrow gaps and fine strokes must remain readable.
3. Inspect PDF image objects if the workflow requires vector artwork. Account for intentional photos elsewhere on the page.
4. Keep the SVG master alongside the document-generation code. Recheck the PDF after changing the artwork or its rendering dependencies.

An SVG can itself contain a raster image. Reading that wrapper does not recover paths from its pixels. The [embedded-image diagnosis](https://perfectvector.com/blog/svg-contains-raster-image) helps distinguish a vector master from an SVG that still carries a bitmap.

## Handle features the importer cannot reproduce

The current [svglib limitations](https://github.com/deeplook/svglib#known-limitations) include unsupported masks and `foreignObject` elements, ignored stylesheet `@import` rules, and restrictions on CSS and clipping. A browser preview therefore cannot substitute for testing the PDF importer.

Keep a copy of the master before simplifying it. Where a logo depends on an unsupported effect, consider rebuilding that portion as ordinary geometry or using a different export route that you can verify. Retain the original raster when photographic appearance matters more than path editing. A flattened image can preserve appearance, but it changes the vector requirement.

For lettering, choose deliberately between document text and outlined artwork. Keeping words as text allows editing and search, but requires the intended font to be available in the document workflow. Outlining approved logo lettering preserves its shape while giving up normal text editing. Our path-only emblem does not test font handling; use a real sample of your type before relying on the same pipeline.

If you are assembling the document in a typesetting system instead of Python, the [SVG in LaTeX workflow](https://perfectvector.com/blog/svg-in-latex) explains a separate graphics-and-label route.

## Recover a raster-only logo before PDF placement

A legacy PNG on an invoice template is a reasonable candidate for vector recovery when the original logo file is missing. With PerfectVector's [logo vectorizer](https://perfectvector.com/vectorize-logo), preview the raster artwork as SVG, inspect the contours and openings, and download a candidate for your document pipeline.

Check small lettering and borders before importing it. Redraw or retypeset elements that need exact typography, and remove unwanted background geometry in an editor. The [logo vectorization guide](https://perfectvector.com/blog/how-to-vectorize-a-logo) covers that source-to-master decision in more detail.

Then run the actual ReportLab import and PDF checks above. A good trace still has to survive the importer and fit your document. PerfectVector supplies artwork paths; it does not choose ReportLab coordinates, register document fonts, or verify the resulting PDF. For charts, regenerate from the data and plotting source rather than tracing their labels or plotted values.

## FAQ

**Can I pass an SVG to ReportLab as an ordinary bitmap image?**
Use svglib to produce a Drawing and render it with renderPDF for this vector workflow. Converting the SVG to PNG first produces a raster insertion instead.

**Why is my imported SVG smaller than an older example?**
The tested svglib 2.2.0 maps CSS pixels to PDF points at a factor of 0.75. Read the returned drawing dimensions and fit them to an explicit box instead of relying on older pixel-to-point assumptions.

**Does this preserve every SVG effect?**
No. The importer has documented feature limits, including masks and foreignObject. Compare the exported PDF with the intended artwork, even when the script completes without an error.

**Should I vectorize a screenshot of a chart?**
Regenerate a chart from its data and plotting source whenever possible. Reserve logo tracing for suitable decorative artwork whose editable original is missing.

## Sources

1. [svglib — Package and units documentation](https://pypi.org/project/svglib/) — SVG-to-Drawing conversion, installation, and PDF-point sizing.
2. [ReportLab — Graphics](https://docs.reportlab.com/reportlab/userguide/ch11_graphics/) — Drawing objects, PDF rendering, and use as Platypus flowables.
3. [ReportLab — Graphics and text with pdfgen](https://docs.reportlab.com/reportlab/userguide/ch2_graphics/) — Canvas coordinates, points, and transformations.
4. [svglib — Known limitations](https://github.com/deeplook/svglib#known-limitations) — Import restrictions that require checking the finished PDF.

***

Keep the editable original when you have one. If only raster logo artwork remains, [prepare an SVG logo candidate](https://perfectvector.com/vectorize-logo), inspect its paths, then place it at the required size and check the finished PDF.

## Explore

- [Read the HTML article](https://perfectvector.com/blog/reportlab-svg)
- [fpdf2 SVG Images: Keep Paths in Your Python PDF](https://perfectvector.com/blog/fpdf2-svg-image.md)
- [PDFKit SVG: Place a Vector Logo Without Flattening It](https://perfectvector.com/blog/pdfkit-svg.md)
- [Product facts](https://perfectvector.com/product-facts.md)
- [FAQ](https://perfectvector.com/faq.md)
- [Pricing and credits](https://perfectvector.com/pricing.md)
