PerfectVector
Autor: Irene Kim9 min czytania

PDFKit SVG: umieść logo wektorowe bez spłaszczania

Wstaw kompletne logo SVG do dokumentu PDFKit, ustaw jego rozmiar w punktach i sprawdź zapisany PDF pod kątem ścieżek, otwartych kształtów, brakujących elementów i osadzonych obrazów.

Na tej stronie

Aby umieścić kompletne logo SVG w pliku PDF generowanym w Node, użyj svg-to-pdfkit z PDFKit i przekaż kod SVG do SVGtoPDF(doc, svg, x, y, options). Wbudowana metoda doc.path() w PDFKit przyjmuje dane ścieżki SVG, takie jak wartość atrybutu d ścieżki. Nie importuje całego dokumentu SVG, jego pozostałych kształtów ani stylów.

To rozróżnienie ma znaczenie w przypadku logo z kilkoma kolorami i otworem pośrodku. Skopiowanie jednej ścieżki może pominąć część grafiki. Zamiana całego logo na PNG zachowuje jego rastrowy wygląd, ale oznacza rezygnację z opartego na ścieżkach pliku PDF, który chcesz uzyskać.

W tym poradniku używamy oryginalnego emblematu, kompletnego skryptu Node i analizy zapisanego pliku PDF. Jeśli masz już edytowalne logo wektorowe, zachowaj je jako źródło. Odtwarzanie grafiki z obrazu rastrowego należy wykonać przed tym etapem importu.

Wybierz wstawienie całego SVG albo pojedynczej ścieżki

Dokumentacja grafiki wektorowej PDFKit opisuje parser ścieżek i powiązane z nim metody rysowania. Osobna biblioteka SVG-to-PDFKit obsługuje kompletny kod SVG.

Dane wejściowe, które maszSposób użyciaCo nadal musisz zrobić
Kompletny SVG z kilkoma kształtamiSVGtoPDF(doc, svgText, x, y, options)Sprawdź rozmiar, zaimportowane elementy i gotowy PDF
Wartość d jednej ścieżkidoc.path(pathData), a następnie wypełnienie lub obrysSamodzielnie określ wypełnienie i obrys, zastosuj przekształcenia i dodaj pozostałe kształty
PNG lub JPEG, który ma pozostać bitmapądoc.image(...)Ustaw położenie i sprawdź efektywną rozdzielczość obrazu

Dokumentacja obrazów PDFKit wymienia PNG i JPEG jako formaty obsługiwane przez doc.image(). Nie traktuj tego wywołania jako importera kompletnego SVG.

Oto przykład poprawnego użycia API ścieżek:

doc.save();
doc.fillColor('#eeaa42');
doc.path('M125 100L175 20L225 100Z').fill();
doc.restore();

Rysuje on trójkąt z naszego emblematu we współrzędnych jego ścieżki. Nie odtwarza turkusowego pierścienia ani paska z innej części pliku źródłowego. Jeśli te elementy mają tworzyć całość, użyj opisanej poniżej metody importu całego dokumentu.

Jeśli składasz PDF w przeglądarce za pomocą jsPDF, skorzystaj z osobnej instrukcji pracy z SVG w jsPDF. W przypadku dokumentu tworzonego z komponentów React użyj instrukcji umieszczania logo SVG w React-pdf. Dla dokumentów w Pythonie porównaj import i sprawdzanie rozmiaru w ReportLab z bezpośrednim umieszczaniem SVG w fpdf2.

Uruchom mały przykład z przypiętymi wersjami pakietów

Uruchomiliśmy ten przykład z PDFKit 0.20.2 i SVG-to-PDFKit 0.1.8. To przetestowana para wersji zależności; po aktualizacji któregokolwiek pakietu sprawdź własny plik wynikowy.

W nowym projekcie Node zainstaluj:

npm install --save-exact pdfkit@0.20.2 svg-to-pdfkit@0.1.8

Zapisz poniższy kod jako logo.svg. Pierścień i jego otwór tworzą jedną ścieżkę z fill-rule="evenodd"; złoty trójkąt i turkusowy pasek są osobnymi kształtami. Plik nie zawiera fontów, obrazów ani efektów.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 120">
  <path fill="#147d78" fill-rule="evenodd"
    d="M110 60A50 50 0 1 1 10 60A50 50 0 1 1 110 60Z
       M85 60A25 25 0 1 1 35 60A25 25 0 1 1 85 60Z"/>
  <path fill="#eeaa42" d="M125 100L175 20L225 100Z"/>
  <rect x="227" y="20" width="8" height="80" fill="#147d78"/>
</svg>

Zapisz poniższy kod jako place-logo.cjs w tym samym katalogu, a następnie uruchom node place-logo.cjs:

const fs = require('node:fs');
const { finished } = require('node:stream/promises');
const PDFDocument = require('pdfkit');
const SVGtoPDF = require('svg-to-pdfkit');
 
async function main() {
  const svg = fs.readFileSync('logo.svg', 'utf8');
  const doc = new PDFDocument({ size: [800, 450], margin: 0 });
  const output = fs.createWriteStream('logo.pdf');
  doc.pipe(output);
  const warnings = [];
  SVGtoPDF(doc, svg, 72, 150, {
    width: 180, height: 90,
    preserveAspectRatio: 'xMinYMin meet',
    warningCallback: message => warnings.push(message),
  });
  SVGtoPDF(doc, svg, 432, 150, {
    width: 90, height: 45,
    preserveAspectRatio: 'xMinYMin meet',
    warningCallback: message => warnings.push(message),
  });
  doc.end();
  await finished(output);
  fs.writeFileSync('warnings.json', JSON.stringify(warnings, null, 2));
  if (warnings.length) process.stderr.write(warnings.join('\n') + '\n');
}
main().catch(error => {
  process.stderr.write(error.stack + '\n');
  process.exitCode = 1;
});

PDFKit tworzy strumień. Wywołanie doc.end() kończy dokument; skrypt następnie czeka na zakończenie strumienia wyjściowego, zanim zakończy działanie. Dokumentacja wprowadzająca wyjaśnia model strumieniowy i wymiary stron wyrażone w punktach PDF, przy przeliczniku 72 punktów na cal.

W tym przykładzie dwa obszary wyświetlania mają wymiary 180 × 90 pt i 90 × 45 pt, czyli 2,5 × 1,25 cala i 1,25 × 0,625 cala. Oba odpowiadają proporcjom 2:1 źródłowego viewBox. Narysowane kształty mają marginesy wewnątrz tego viewBox, więc widoczna grafika zajmuje mniejszy obszar niż obszar wyświetlania. Przy wyrównywaniu logo do sąsiadującego tekstu mierz osobno obszar roboczy i faktycznie narysowaną grafikę.

Dokumentacja importera określa width i height jako początkowy obszar wyświetlania. Opcja preserveAspectRatio steruje dopasowaniem do niego. Ten przykład używa zgodnych proporcji i jawnych wymiarów, aby nie polegać na domyślnym obszarze wielkości strony. Nie używaj assumePt jako uniwersalnego rozwiązania problemu niespodziewanie małego logo; najpierw sprawdź wymiary źródła, viewBox i docelowy obszar wyświetlania.

Sprawdź strukturę PDF, a następnie jego wygląd

Nasz minimalny plik logo.pdf zawierał jedną stronę o wymiarach 800 × 450 pt. Za pomocą pypdf 6.10.0 znaleźliśmy 24 operacje rysowania krzywych Béziera trzeciego stopnia, dwie operacje wypełnienia według reguły parzystości i zero obrazów na stronie. Zasoby strony nie zawierały fontów ani obiektów XObject. Importer nie zgłosił żadnego ostrzeżenia dla tego przykładu testowego.

Te wyniki pozwalają sformułować wąski wniosek: ten oryginalny emblemat bez obrazów został narysowany za pomocą geometrii PDF w przetestowanych wersjach. Nie dowodzą, że dowolny SVG staje się w całości wektorowym plikiem PDF. Logo zawierające osadzoną fotografię nadal wymaga osobnej analizy.

Wyrenderowaliśmy też wersję z opisami za pomocą Popplera. Wykorzystuje ten sam SVG i dwa rozmiary obszaru wyświetlania, a umieszczone grafiki przeniesiono do paneli porównawczych. Jasne tło panelu pozostaje widoczne przez oba pierścienie, a trójkąt i wąski pasek pozostają oddzielone od pierścienia.

Wyrenderowany PDF przedstawiający turkusowy pierścień, złoty trójkąt i turkusowy pasek w obszarach wyświetlania o wymiarach 180 na 90 punktów oraz 90 na 45 punktów
Oryginalny emblemat wyrenderowany z pliku PDF przy dwóch rozmiarach obszaru wyświetlania. Obraz na stronie jest podglądem rastrowym; osobna analiza PDF wykazała operacje rysowania i brak osadzonych obrazów.

Sama ostrość po powiększeniu jest słabym dowodem: odpowiednio duża bitmapa też może wyglądać ostro. Z kolei znalezienie operacji krzywej gdzieś w raporcie nic nie mówi o tym, czy jego logo zostało zrasteryzowane. Wyodrębnij grafikę w małym testowym pliku PDF, zanim przeanalizujesz dokument zawierający także zdjęcia i wykresy.

W przypadku własnego logo wykonaj oba kroki:

  1. Sprawdź zawartość stron PDF i obiekty, do których się odwołują, za pomocą narzędzia do analizy PDF. Poszukaj instrukcji rysowania w miejscu, w którym rysowane jest logo, i uwzględnij wszystkie obiekty obrazów. Bardziej złożone pliki PDF mogą umieszczać zawartość wewnątrz obiektów Form XObject, więc samo zliczenie obiektów na najwyższym poziomie nie zawsze wystarcza.
  2. Otwórz zapisany PDF w programie, w którym ma być oglądany, i porównaj go ze źródłem. Sprawdź otwór, osobne kolory, przycinanie, marginesy i drobne szczegóły w rzeczywistym rozmiarze, w jakim plik ma być dostarczony.

Przechowuj oryginalny SVG obok kodu generującego PDF. Jeśli plik źródłowy jedynie opakowuje piksele, skorzystaj z diagnostyki osadzonych obrazów, zanim założysz, że rozszerzenie SVG dowodzi czegokolwiek na temat jego geometrii.

Używaj fontów i efektów w ramach przetestowanego sposobu pracy

SVG-to-PDFKit wymienia filtry i foreignObject wśród nieobsługiwanych funkcji. Dokumentuje też wymagania dotyczące rejestracji fontów i funkcji zwrotnych. W małym logo przetwarzanym po stronie serwera używaj jawnych atrybutów prezentacyjnych SVG i analizuj ostrzeżenia razem z wyrenderowanym wynikiem. Style CSS wyliczone przez przeglądarkę stanowią osobną opcję dla przekazanego elementu SVG; korzystanie z nich nie jest tym samym co przekazanie kodu SVG do tego skryptu Node. Zobacz dokumentację funkcji i fontów biblioteki.

Nasz emblemat celowo nie zawiera tekstu. W przypadku rzeczywistych napisów dostarcz i przetestuj odpowiednie fonty albo zachowaj zatwierdzone napisy zamienione na kontury w głównym pliku wektorowym. Dokumentacja fontów PDFKit opisuje osadzanie i rejestrację fontów. Tekst dokumentu i kontury logo mają różne wymagania dotyczące edycji; obrysowanie zrzutu ekranu napisu nie pozwoli zidentyfikować oryginalnego fontu.

Jeśli znak marki zależy od efektu, którego ten importer nie potrafi odtworzyć, przebuduj ten efekt jako odpowiednią geometrię albo wybierz inny sposób eksportu i zweryfikuj go. Wstawienie obrazu rastrowego jest również prawidłowym wyborem, gdy wygląd ma większe znaczenie niż zachowanie ścieżek. Nie opisuj tego wyboru jako eksportu zachowującego grafikę wektorową.

Przykład używa kolorów RGB. Samo zachowanie ścieżek nie potwierdza spełnienia wymagań drukarni dotyczących kolorów, PDF/X ani przygotowania do druku. Uzgodnij je z odbiorcą; poradnik dotyczący formatów logo pomaga rozróżnić edytowalny plik główny i plik do przekazania.

Odtwórz logo dostępne tylko jako obraz rastrowy przed jego wstawieniem

Jeśli oryginalne logo istnieje tylko jako PNG lub JPG, narzędzie do wektoryzacji logo PerfectVector może przygotować wersję SVG do oceny przed etapem pracy z PDFKit. Porównaj kontury, małe otwory i oddzielne obszary kolorów ze źródłem, a następnie poddaj tę wersję takim samym kontrolom umieszczenia i pliku PDF.

Używaj oryginalnej grafiki wektorowej zawsze, gdy jest dostępna. W przypadku uszkodzonych napisów lub geometrii marki wymagającej dokładnego odwzorowania wpisz ponownie tekst albo przerysuj dany fragment w edytorze. Poradnik wektoryzacji logo wyjaśnia, jak podjąć tę decyzję dotyczącą źródła. PerfectVector przygotowuje ścieżki grafiki; PDFKit i jego importer zajmują się umieszczeniem jej w dokumencie. Emblemat testowy z tego artykułu jest ręcznie utworzoną grafiką wektorową, a nie wynikiem konwersji poddanym pomiarom.

Najczęściej zadawane pytania

Czy PDFKit może zaimportować kompletny SVG za pomocą doc.path()? Nie. Metoda ścieżki odczytuje dane ścieżki SVG. W tym sposobie pracy użyj SVG-to-PDFKit do importu całego dokumentu albo samodzielnie narysuj każdy kształt i nadaj mu styl.

Czy SVG-to-PDFKit gwarantuje PDF bez obrazów rastrowych? Nie. PDF utworzony z przetestowanego emblematu bez obrazów zawierał operacje rysowania i nie zawierał żadnych obrazów na stronie. Sprawdź własne dane wejściowe i wyeksportowany PDF, zwłaszcza gdy SVG zawiera osadzone obrazy lub funkcje spoza zestawu obsługiwanego przez importer.

Dlaczego widoczne logo jest mniejsze niż ustawione width i height? Te opcje określają obszar wyświetlania przy imporcie. Pusta przestrzeń wewnątrz źródłowego viewBox pozostaje częścią układu, a dopasowanie z zachowaniem proporcji może pozostawić dodatkową przestrzeń. Sprawdź granice grafiki, zanim zmienisz żądany rozmiar w PDF.

Źródła

  1. PDFKit — Vector graphics — Dokumentuje parsowanie danych ścieżek SVG, operacje wypełnienia i obrysu oraz stan graficzny.
  2. SVG-to-PDFKit — Usage and limitations — Definiuje wstawianie całego SVG, opcje obszaru wyświetlania, ostrzeżenia, fonty i obsługiwane funkcje.
  3. PDFKit — Images — Wymienia formaty bitmapowe akceptowane przez API obrazów.
  4. PDFKit — Getting started — Wyjaśnia strumienie dokumentów, kończenie dokumentu i ustalanie rozmiaru strony w punktach PDF.
  5. PDFKit — Fonts — Opisuje osadzanie fontów i rejestrowanie ich pod nazwami.

Jeśli logo w Twoim dokumencie jest początkowo obrazem rastrowym, przygotuj wersję SVG do oceny za pomocą PerfectVector, sprawdź jej otwory i kontury, a następnie umieść ją w wymaganym rozmiarze w PDF i sprawdź zapisany plik.

Więcej z bloga

Zacznij od czystszego SVG,
który łatwiej edytować