Obrazy SVG w WeasyPrint: napraw brakujące logo w plikach PDF
Napraw brakujące logo SVG w plikach PDF z WeasyPrint za pomocą poprawnego bazowego adresu URL i jawnego określenia rozmiaru w CSS, a następnie sprawdź ścieżki wektorowe, proporcje i grafikę w zapisanym pliku PDF.
Na tej stronie
WeasyPrint może umieścić SVG w pliku PDF za pomocą elementu obrazu HTML. Jeśli logo znika, gdy przekazujesz HTML jako ciąg znaków, najpierw sprawdź adres URL obrazu: ścieżka względna wymaga bazowego adresu URL. Gdy plik już się załaduje, ustaw jego rozmiar wydruku w CSS i sprawdź zapisany plik PDF. Aktualna dokumentacja API WeasyPrint opisuje ten wymóg dotyczący base_url.
Poniższy przykład odtwarza przypadek brakującego obrazu przy użyciu autorskiego logo w kształcie ramki. Sprawdza też, czy naprawiony plik PDF zawiera wektorową geometrię rysunku o żądanym rozmiarze. Jeśli masz już SVG, zacznij od tego pliku. Wektoryzacja pojawia się w tym procesie tylko wtedy, gdy grafika źródłowa istnieje w postaci pikseli.
Sprawdź ładowanie, zanim zmienisz grafikę
Plik PDF może powstać nawet wtedy, gdy brakuje w nim logo. Sprawdź ostrzeżenie dotyczące zasobu, rozwiąż problem ze ścieżką obrazu i ponownie wyrenderuj ten sam SVG, zanim zaczniesz edytować jego kształty lub konwertować go do innego formatu.
Odtwórz problem z brakującym SVG w małym dokumencie
Testowaliśmy przy użyciu Pythona 3.13.9 i WeasyPrint 70.0. Użyj środowiska projektu i zainstaluj wskazaną wersję:
python -m pip install "weasyprint==70.0"
python -m weasyprint --infoWeasyPrint potrzebuje też bibliotek natywnych, w tym Pango. Skorzystaj z instrukcji instalacji dla danego systemu operacyjnego, jeśli import lub polecenie sprawdzające wersję kończy się błędem. Brak biblioteki natywnej to inny problem niż brak logo.
Utwórz taką strukturę folderów:
example/
render.py
assets/
logo.svgZapisz tę autorską grafikę demonstracyjną jako assets/logo.svg. Otwór pośrodku daje Ci do sprawdzenia coś bardziej użytecznego niż pełny prostokąt. To ręcznie opracowana geometria, a nie wynik konwersji w 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>Umieść poniższy kod w 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")Uruchom python render.py. W naszym pierwszym pliku PDF nie było ramki, a zamiast niej pojawił się tekst alternatywny obrazu. Dziennik zawierał:
Relative URI reference without a base URI: assets/logo.svgDrugi plik PDF pokazywał turkusową ramkę z zachowanym otworem. Oba wywołania utworzyły plik, więc samo istnienie pliku PDF nie było użytecznym sprawdzianem powodzenia.
Zapewnij ścieżkom względnym stały folder początkowy
assets/logo.svg wskazuje plik względem innej lokalizacji. base_url w drugim wywołaniu podaje tę lokalizację początkową. root.as_uri() tworzy bezwzględny URI pliku; końcowy ukośnik sprawia, że jest on bazą wskazującą katalog. Logo pozostaje w tym samym folderze assets, a zawartość SVG się nie zmienia.
Użycie Path(__file__) utrzymuje też powiązanie przykładu z folderem skryptu, gdy uruchamiasz go z innego katalogu roboczego. W notatniku użyj zamiast tego jawnie wskazanego folderu projektu, ponieważ __file__ zwykle nie jest tam dostępne.

Jest jeszcze jeden przydatny test kontrolny. Zapisz HTML jako invoice.html obok render.py i wczytaj sam plik:
HTML(filename=str(root / "invoice.html")).write_pdf(
root / "from-file.pdf"
)WeasyPrint może wyznaczyć bazę na podstawie nazwy pliku wejściowego lub adresu URL. Nasz test z plikiem dał taką samą ramkę jak przypadek z jawnie określoną bazą. Ciąg znaków zawierający HTML nie ma odpowiadającej mu nazwy pliku, z której można by wywnioskować tę bazę. Te tryby wejściowe i ich reguły ustalania bazy opisano w dokumentacji konstruktora HTML.
W przypadku obrazu dostępnego po zalogowaniu poprawny adres URL nadal może nie wystarczyć. Dokumentacja mechanizmu pobierania zasobów z adresów URL podaje, że domyślny klient HTTP nie zapewnia obsługi plików cookie ani uwierzytelniania. Użyj zatwierdzonego w Twojej aplikacji sposobu pobierania zasobów i przetestuj go w środowisku generującym PDF. Nie zakładaj, że logo widoczne w przeglądarce po zalogowaniu jest dostępne dla procesu tworzącego PDF.
Ustaw rozmiar obrazu niezależnie od rozmiaru strony PDF
Przykład używa @page do określenia arkusza A4 i marginesów, a .logo ustawia szerokość obrazu na 60 mm. Proporcje źródłowe 2:1 sprawiają, że przy height: auto ma on 30 mm wysokości. W naszym zapisanym pliku PDF ramka miała wymiary 60 × 30 mm i zaczynała się 20 mm od górnej i lewej krawędzi strony.
Tutaj rysunek wypełnia cały swój viewBox. Twoje logo może mieć pustą przestrzeń wewnątrz tego prostokąta, więc pole obrazu o szerokości 60 mm może zawierać wyraźnie węższy znak. Sprawdź obszar SVG, zanim spróbujesz skompensować tę różnicę, arbitralnie zwiększając szerokość w CSS. Poradnik dotyczący rozmiaru importowanego SVG wyjaśnia to rozróżnienie bardziej szczegółowo.
Podczas sprawdzania wymiarów fizycznych pozostaw domyślne zoom=1 w write_pdf(). Dokumentacja wyjścia PDF WeasyPrint ostrzega, że zmiana zoom skaluje również fizyczne jednostki CSS i nazwane rozmiary stron.
| Co widzisz | Co sprawdzić najpierw | Następny krok |
|---|---|---|
| Tekst alternatywny zastępuje logo | Adres URL obrazu i dziennik zasobów | Podaj prawidłowy bazowy adres URL lub dostępny bezwzględny adres URL |
| Logo ma niewłaściwy rozmiar | Szerokość w CSS i proporcje źródła | Ustaw szerokość w jednostkach fizycznych i sprawdź obszar SVG |
| Brakuje części grafiki | Granice źródła i konkretną funkcję SVG | Ogranicz przykład do niewielkiego przypadku odtwarzającego błąd i porównaj wyeksportowany PDF |
| Renderowanie lokalne działa, a na serwerze nie | Dostępne pliki, fonty i dostęp do adresów URL | Przetestuj przy użyciu zasobów procesu uruchomionego we wdrożonym środowisku |
Sprawdź zawartość i wygląd pliku PDF
Aktualna dokumentacja formatów WeasyPrint podaje, że obrazy SVG są renderowane w plikach PDF jako grafika wektorowa. Nie oznacza to, że każdy plik z rozszerzeniem .svg zawiera wyłącznie grafikę wektorową: SVG może zawierać osadzony obraz rastrowy. Sprawdź to za pomocą diagnostyki osadzonych obrazów, jeśli w wyniku nadal widać piksele.
W przypadku tego prostego materiału testowego sprawdziliśmy zapisane pliki PDF za pomocą PyMuPDF 1.26.7:
| Przypadek wejściowy | Rekordy rysunków | Osadzone obrazy | Widoczna ramka |
|---|---|---|---|
| Ciąg znaków HTML bez bazy | 0 | 0 | Brak; pojawił się tekst alternatywny |
| Ciąg znaków HTML z folderem jako bazą | 1 | 0 | 60 × 30 mm, otwór zachowany |
| HTML wczytany na podstawie nazwy pliku | 1 | 0 | Taki sam wynik jak dla ciągu znaków z określoną bazą |
Te wyniki dotyczą dostarczonej ramki, a nie wszystkich funkcji SVG. Jedna ścieżka złożona również nie oznacza jednego widocznego kształtu: jej wewnętrzna podścieżka definiuje otwór.
Aby sprawdzić swój resolved.pdf, zainstaluj pymupdf==1.26.7 i uruchom:
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)Dokumentacja klasy Page w PyMuPDF opisuje metody sprawdzania rysunków i obrazów. Te liczby służą diagnostyce i nie stanowią potwierdzenia wierności odwzorowania. Otwórz też plik PDF: sprawdź otwór, kolory, proporcje i ewentualne napisy w rzeczywistym rozmiarze, w jakim dokument trafi do odbiorcy. Sprawdzaj kolejno poszczególne elementy złożonej grafiki i powtarzaj kontrole przy aktualizacji silnika renderującego.
Kiedy najpierw przygotować nowy SVG
Gdy jedyne dostępne logo to PNG lub JPG, narzędzie do wektoryzacji logo PerfectVector może przygotować plik SVG do sprawdzenia, zanim umieścisz go w dokumencie HTML. Sprawdź kontury, małe otwory i napisy w edytorze, a następnie przetestuj SVG w tym samym procesie WeasyPrint. Poradnik wektoryzacji obrazów wyjaśnia, co się zmienia, gdy piksele stają się ścieżkami.
Zachowaj oryginalny edytowalny SVG, jeśli istnieje. Popraw odwołanie do jego pliku lub układ zamiast ponownie go wektoryzować. Fotografie mogą pozostać obrazami rastrowymi, a dokładne odwzorowanie firmowych napisów może wymagać oryginalnego fontu lub ręcznego przerysowania. Wektoryzacja nie naprawia brakujących plików na serwerze, uwierzytelniania ani nieobsługiwanych funkcji renderowania.
Jeśli potrzebujesz jedynie przekonwertować SVG na osobną stronę PDF, proces eksportu w CairoSVG obejmuje to mniejsze zadanie. WeasyPrint nadaje się do dokumentu HTML, w którym grafika dzieli stronę z inną treścią.
FAQ
Dlaczego WeasyPrint tworzy PDF bez mojego logo SVG? Mimo błędu ładowania obrazu pozostała część dokumentu może nadal zostać wyrenderowana. Sprawdź dziennik zasobów i adres URL obrazu. W dostarczonym teście ciąg znaków HTML ze względną ścieżką obrazu wymagał jawnie określonego bazowego adresu URL.
Czy muszę najpierw przekonwertować SVG na PNG? Nie. WeasyPrint przyjmuje obrazy SVG. Zachowaj obsługiwaną grafikę wektorową jako SVG, jeśli taki ma być wynik, i sprawdź zapisany plik PDF. Eksport rastrowy jest alternatywą, gdy świadomie stawiasz wygląd ponad geometrią wektorową.
Czy base_url zmienia rozmiar wydruku logo? Nie. Zapewnia bazę do rozwiązywania względnych adresów URL zasobów. Ustaw rozmiar umieszczanego obrazu za pomocą CSS, a wymiary SVG i viewBox sprawdź osobno.
Źródła
- WeasyPrint API reference — Opisuje dane wejściowe HTML, bazowe adresy URL, renderowanie SVG w wynikowym PDF oraz działanie parametru zoom przy generowaniu PDF.
- WeasyPrint First Steps — Obejmuje instalację i pobieranie zasobów, w tym ograniczenia uwierzytelniania.
- PyMuPDF Page reference — Opisuje użyte w przykładzie metody sprawdzania rysunków i osadzonych obrazów.
Masz tylko logo rastrowe? Przygotuj SVG za pomocą PerfectVector, sprawdź jego kształty i napisy, a następnie umieść go w swoim HTML i zweryfikuj jego wygląd oraz wymiary fizyczne w zapisanym pliku PDF.
Więcej z bloga

Obrazy SVG w Graphviz: zadbaj o przenośność grafiki węzłów
Dodaj grafikę SVG do węzła Graphviz, sprawdź odwołanie do obrazu i przetestuj kompletny pakiet zasobów, porównując go z przeniesionym diagramem oraz samowystarczalną kopią do przekazania.

Matplotlib SVG: Zachowaj wykres i grafikę logo jako ścieżki
Wyeksportuj wykres z Matplotlib jako SVG, połącz go z osobnymi ścieżkami logo za pomocą svgutils i sprawdź plik przekazywany odbiorcy pod kątem osadzonych pikseli, rozmieszczenia i zmian czcionek.