vs. Rust-PDF-Bibliotheken
PDF Oxide im Vergleich mit den meistgenutzten Rust-PDF-Crates: lopdf, printpdf, pdf-rs und pdf_extract. Jede zielt auf eine andere Abstraktionsebene und einen anderen Satz von Anwendungsfällen ab.
Zusammenfassung
| PDF Oxide | lopdf | printpdf | pdf-rs | pdf_extract | |
|---|---|---|---|---|---|
| API-Ebene | High-Level | Low-Level | Mid-Level (Erstellung) | Low-Level (Lesen) | Mid-Level (Lesen) |
| PDFs lesen | Ja | Ja | Nein | Ja | Ja |
| PDFs schreiben | Ja | Ja | Ja | Nein | Nein |
| Textextraktion | Ja (High-Level) | Manuell | Nein | Manuell | Ja (einfach) |
| Bildextraktion | Ja (High-Level) | Manuell | Nein | Manuell | Nein |
| Formularfelder | Lesen + Schreiben | Manuell | Nein | Nur Lesen | Nein |
| PDF-Erstellung | Ja | Ja | Ja | Nein | Nein |
| Markdown-/HTML-Eingabe | Ja | Nein | Nein | Nein | Nein |
| Bestehende PDFs bearbeiten | Ja | Ja (Low-Level) | Nein | Nein | Nein |
| Annotationen | Lesen + Schreiben | Manuell | Nein | Nur Lesen | Nein |
| Verschlüsselung | Lesen + Schreiben | Nein | Nein | Nein | Nein |
| PDF/A-Validierung | Ja | Nein | Nein | Nein | Nein |
| Rendering | Ja (tiny-skia) | Nein | Nein | Teilweise | Nein |
| Python-Bindings | Ja | Nein | Nein | Nein | Nein |
| Lizenz | MIT | MIT | MIT | MIT | Apache-2.0 |
Alle Bibliotheken sind permissiv lizenziert. Die Unterschiede liegen im Umfang und in der Abstraktionsebene.
Leistungsvergleich
Benchmark über das vollständige Korpus (3.830 PDFs)
Getestet auf dem vollständigen Korpus aus 3.830 PDFs – drei unabhängigen, öffentlich verfügbaren Testsuiten, die die Konformität mit der PDF-Spezifikation (veraPDF, 2.907 Dateien), reale Grenzfälle beim Browser-Rendering (Mozilla pdf.js, 897 Dateien) sowie Sicherheits- und Robustheits-Stresstests einschließlich fehlerhafter Strukturen und durch Fuzzing erzeugter Beschädigungen (DARPA SafeDocs, 26 Dateien) abdecken. Siehe Details zum vollständigen Korpus.
| Bibliothek | Mittelwert | p99 | Erfolgsquote | Textextraktion | Anmerkungen |
|---|---|---|---|---|---|
| PDF Oxide | 0,8 ms | 9 ms | 100 % | Integriert, produktionsreif | Unicode, CJK, Leserichtung |
| oxidize_pdf | 13,5 ms | 11 ms | 99,1 % | Einfach | Maximaler Ausreißer 48 s |
| unpdf | 2,8 ms | 10 ms | 95,1 % | Einfach | 185 Fehlschläge im vollständigen Korpus |
| pdf_extract | 4,08 ms | 37 ms | 91,5 % | Einfach | Verfehlt komplexe Layouts |
| lopdf | 0,3 ms | 2 ms | 80,2 % | Keine integrierte Extraktion | Scheitert bei 20 % der PDFs |
lopdf ist bei den PDFs, die es parsen kann, schneller – aber es scheitert bei 20 % des Korpus und bietet keine Textextraktion. Font-Decodierung, CMap-Auflösung und Abstandsanalyse müssten Sie selbst implementieren.
pdf_extract bietet einfache Textextraktion, hat aber eine Erfolgsquote von 91,5 % und tut sich schwer mit komplexen Layouts, CJK-Text und getaggten PDFs. oxidize_pdf hat eine ordentliche Zuverlässigkeit (99,1 %), ist aber bei der mittleren Extraktionszeit 17× langsamer als pdf_oxide, mit einem Worst-Case-Ausreißer von 48 Sekunden. unpdf verarbeitet das vollständige Korpus, scheitert aber bei 185 PDFs.
PDF Oxide ist die einzige Rust-Crate, die 100 % Zuverlässigkeit mit produktionsreifer Textextraktion verbindet.
Vergleich des API-Designs
PDF Oxide: High-Level, aufgabenorientiert
PDF Oxide bietet speziell zugeschnittene Methoden für gängige Aufgaben. Sie arbeiten mit Text, Bildern und Formularfeldern – nicht mit PDF-Objekten und -Dictionaries.
use pdf_oxide::PdfDocument;
let mut doc = PdfDocument::open("report.pdf")?;
// Text extraction -- one call
let text = doc.extract_text(0)?;
println!("{}", text);
// Styled spans with font metadata
let spans = doc.extract_spans(0)?;
for span in &spans {
println!("'{}' font={} size={:.1}pt", span.text, span.font_name, span.font_size);
}
// Image extraction
let images = doc.extract_images(0)?;
for img in &images {
println!("{}x{} {:?}", img.width, img.height, img.format);
}
// Form fields
let fields = doc.extract_form_fields()?;
for field in &fields {
println!("{}: {:?}", field.name, field.value);
}
Die PDF-Erstellung ist ebenso unkompliziert:
use pdf_oxide::api::Pdf;
// From Markdown
let pdf = Pdf::from_markdown("# Report\n\n| A | B |\n|---|---|\n| 1 | 2 |")?;
pdf.save("report.pdf")?;
// From HTML
let pdf = Pdf::from_html("<h1>Report</h1><p>Content here.</p>")?;
pdf.save("report.pdf")?;
lopdf: Low-Level-Objektmanipulation
lopdf gibt Ihnen direkten Zugriff auf PDF-Objekte, Streams und die Querverweistabelle. Um es effektiv zu nutzen, müssen Sie die PDF-Spezifikation verstehen. Es gibt keine integrierte Textextraktion – Sie navigieren selbst durch Dictionaries und decodieren Streams.
use lopdf::Document;
let doc = Document::load("report.pdf")?;
// Get page dictionary
let page_id = doc.page_iter().next().unwrap();
let page = doc.get_dictionary(page_id)?;
// Get content stream -- manual work
let contents = page.get("Contents")?;
let stream = doc.get_object(contents.as_reference()?)?;
// To extract text you must:
// 1. Parse the content stream operators
// 2. Resolve font references from /Resources
// 3. Decode CMap/ToUnicode mappings
// 4. Apply text matrix transformations
// 5. Handle encoding differences
//
// lopdf does not provide any of this -- it is raw object access
println!("Page has {} objects", doc.objects.len());
lopdf ist das richtige Werkzeug, wenn Sie die PDF-Struktur direkt manipulieren müssen: Dokumente zusammenführen, Objekt-Streams umschreiben oder spezialisierte PDF-Prozessoren bauen.
printpdf: nur PDF-Erstellung
printpdf ist eine Bibliothek nur zur Erstellung. Sie kann bestehende PDFs weder lesen noch parsen. Sie bietet eine typisierte API, um PDF-Dokumente von Grund auf mit Text, Bildern und Vektorgrafiken zu erstellen.
use printpdf::*;
let (doc, page1, layer1) = PdfDocument::new(
"Report", Mm(210.0), Mm(297.0), "Layer 1"
);
let current_layer = doc.get_page(page1).get_layer(layer1);
// Add text -- requires manual font loading
let font = doc.add_builtin_font(BuiltinFont::Helvetica)?;
current_layer.use_text("Hello World", 24.0, Mm(10.0), Mm(280.0), &font);
// Save
doc.save(&mut std::io::BufWriter::new(
std::fs::File::create("output.pdf")?,
))?;
// Cannot read existing PDFs
// Cannot extract text, images, or form fields
printpdf ist das richtige Werkzeug, wenn Sie nur neue PDFs generieren müssen und eine saubere, fokussierte Erstellungs-API wünschen.
pdf-rs: Low-Level-PDF-Lesen
pdf-rs parst die PDF-Struktur in Rust-Typen, bietet aber nur minimale High-Level-Funktionalität. Sie erhalten typisierten Zugriff auf PDF-Objekte, müssen aber Textdecodierung, Font-Auflösung und das Parsen von Content-Streams weiterhin selbst übernehmen.
use pdf::file::FileOptions;
let file = FileOptions::cached().open("report.pdf")?;
// Access page objects
let page = file.get_page(0)?;
let media_box = page.media_box()?;
println!("Page size: {:?}", media_box);
// Content stream access -- low-level
if let Some(ref contents) = page.contents {
// Returns raw operations -- you must interpret them
// No built-in text assembly, font decoding, or layout analysis
}
// Cannot write or modify PDFs
pdf-rs ist das richtige Werkzeug, wenn Sie einen typsicheren PDF-Parser für Analyse, Validierung oder den Aufbau eines eigenen Renderers benötigen.
Funktionsvergleich nach Aufgabe
Textextraktion
| Bibliothek | Integriert | Qualität | Erforderlicher Aufwand |
|---|---|---|---|
| PDF Oxide | Ja | Produktionsreif (Unicode, CJK, Leserichtung) | Ein Methodenaufruf |
| pdf_extract | Ja | Einfach (verfehlt komplexe Layouts) | Ein Methodenaufruf |
| lopdf | Nein | – | Hunderte Zeilen eigener Code |
| printpdf | Nein | – | Nicht möglich (nur Schreiben) |
| pdf-rs | Nein | – | Erheblicher eigener Code nötig |
PDF Oxide übernimmt die CMap-/ToUnicode-Decodierung, Abstände auf Basis von Font-Metriken, die Leserichtung über den Strukturbaum und die Rekonstruktion von Ligaturen. Eine gleichwertige Funktionalität auf Basis von lopdf oder pdf-rs zu implementieren, erfordert Tausende Codezeilen und tiefes Wissen über die PDF-Spezifikation.
PDF-Erstellung
| Bibliothek | Ansatz | Markdown-/HTML-Eingabe | Tabellen | Barcodes |
|---|---|---|---|---|
| PDF Oxide | High-Level + Low-Level | Ja | Ja | Ja |
| lopdf | Roher Objektaufbau | Nein | Nein | Nein |
| printpdf | Typisierte Layer-API | Nein | Nein | Nein |
| pdf-rs | – (nur Lesen) | – | – | – |
Verschlüsselung
| Bibliothek | Verschlüsselt lesen | Verschlüsselt schreiben | Algorithmen |
|---|---|---|---|
| PDF Oxide | Ja | Ja | RC4-40, RC4-128, AES-128, AES-256 |
| lopdf | Nein | Nein | – |
| printpdf | Nein | Nein | – |
| pdf-rs | Teilweise | Nein | Nur RC4 |
Konformität
| Bibliothek | PDF/A | PDF/X | PDF/UA |
|---|---|---|---|
| PDF Oxide | Validieren + konvertieren | Validieren | Validieren |
| lopdf | Nein | Nein | Nein |
| printpdf | Teilweise (PDF/A-1b-Ausgabe) | Nein | Nein |
| pdf-rs | Nein | Nein | Nein |
Abhängigkeits-Footprint
| Bibliothek | Abhängigkeiten | Kompilierzeit | Binärgröße |
|---|---|---|---|
| PDF Oxide | ~40 (Kern) | ~30 s | ~4 MB |
| lopdf | ~15 | ~10 s | ~1 MB |
| printpdf | ~20 | ~15 s | ~2 MB |
| pdf-rs | ~25 | ~20 s | ~2 MB |
PDF Oxide hat mehr Abhängigkeiten, weil es Font-Parsing, Bilddecodierung, Interpretation von Content-Streams und Verschlüsselung enthält – Funktionen, die die anderen Bibliotheken dem Nutzer überlassen oder ganz weglassen. Mit allen optionalen Features (rendering, barcodes, office) steigt die Zahl auf ~100.
Bibliotheken kombinieren
Da alle permissiv lizenziert sind, können Sie sie in einem einzigen Projekt kombinieren:
[dependencies]
pdf_oxide = "0.3"
lopdf = "0.32" # Optional: raw object access for edge cases
Gängige Muster:
- PDF Oxide + lopdf: Nutzen Sie PDF Oxide für Extraktion und Erstellung und greifen Sie für Grenzfälle, die rohe Objektmanipulation erfordern, auf lopdf zurück.
- PDF Oxide + printpdf: Nutzen Sie PDF Oxide zum Lesen und printpdf für spezialisierte Erstellungs-Workflows.
Anwendungsfall-Matrix
„Ich muss Text aus PDFs extrahieren“
| Crate | Geeignet? | Anmerkungen |
|---|---|---|
| PDF Oxide | Ja | Beste Extraktionsqualität, 100 % Erfolgsquote, Leserichtung, Font-Metadaten |
| pdf_extract | Teilweise | Einfache Extraktion, 91,5 % Erfolgsquote |
| lopdf | Nein | Keine Textextraktion |
| printpdf | Nein | Kann keine PDFs lesen |
| pdf-rs | Teilweise | Einfaches Parsing, keine High-Level-Textextraktion |
„Ich muss PDFs erstellen“
| Crate | Geeignet? | Anmerkungen |
|---|---|---|
| PDF Oxide | Ja | High-Level- (Markdown/HTML) und Low-Level-APIs |
| lopdf | Teilweise | Low-Level-Objektaufbau |
| printpdf | Ja | Saubere Erstellungs-API, kein Lesen |
| pdf-rs | Nein | Nur Lesen |
„Ich muss bestehende PDFs bearbeiten“
| Crate | Geeignet? | Anmerkungen |
|---|---|---|
| PDF Oxide | Ja | DOM-ähnliche Bearbeitung, Annotationen, Formulare |
| lopdf | Teilweise | Low-Level-Objektmanipulation |
| printpdf | Nein | Kann keine PDFs lesen |
| pdf-rs | Nein | Nur Lesen |
„Ich brauche den vollen Lebenszyklus (Extrahieren + Erstellen + Bearbeiten)“
| Crate | Geeignet? | Anmerkungen |
|---|---|---|
| PDF Oxide | Ja | Einzige Crate, die alle drei abdeckt |
| lopdf + printpdf | Teilweise | Zwei Crates, keine Textextraktion |
| pdf-rs + printpdf | Teilweise | Zwei Crates, keine Bearbeitung |
Wann welche verwenden
Wählen Sie PDF Oxide, wenn Sie mehr als eine PDF-Fähigkeit benötigen (Extraktion + Erstellung oder Extraktion + Bearbeitung) und eine einzige, gut getestete Abhängigkeit mit 100 % Zuverlässigkeit wünschen.
Wählen Sie lopdf, wenn Sie Low-Level-Manipulation der PDF-Struktur benötigen und es Ihnen recht ist, direkt mit der PDF-Spezifikation zu arbeiten. Gut für Zusammenführen, Aufteilen und Batch-Verarbeitung von PDFs.
Wählen Sie printpdf, wenn Sie nur PDFs erstellen und sie nie lesen müssen. Die sauberste API für die Erzeugung von Berichten und Dokumenten.
Wählen Sie pdf-rs, wenn Sie einen spezifikationskonformen Parser für die PDF-Analyse benötigen oder Ihre eigene Rendering-Pipeline bauen.
Wählen Sie pdf_extract, wenn Sie einfache Textextraktion benötigen und keine hohe Zuverlässigkeit oder Unterstützung für komplexe Layouts erfordern.
Verwandte Seiten
- Performance-Benchmarks – Benchmark-Ergebnisse über das vollständige Korpus
- Erste Schritte mit Rust – Installation und erste Extraktion
- Rust-API-Referenz – vollständige Rust-API
- vs. Python-PDF-Bibliotheken – Vergleich des Python-Ökosystems