Erste Schritte mit PDF Oxide (Zig)
PDF Oxide ist die schnellste PDF-Bibliothek mit integrierter Textextraktion — 0,8 ms Mittelwert, 100 % Erfolgsquote bei 3.830 PDFs. Das Zig-Binding ist idiomatisches Zig über das pdf_oxide-C-ABI per @cImport — kein Shim, erstklassige C-Interoperabilität. Handles sind Structs mit deinit, und zurückgegebene C-Strings/-Buffer werden in einen vom Aufrufer bereitgestellten Allocator kopiert.
Festgelegt auf Zig 0.15.1 — der Pre-1.0-Build und die C-Import-API ändern sich zwischen Releases, deshalb verwendet CI dieselbe Version.
Installation
Das Binding bindet das cdylib mit den Standard-Features (nicht das Python-Wheel). Bauen Sie die native Bibliothek und verweisen Sie Zig dann auf den Header und das cdylib:
# 1. build the native library (shipped binding feature set)
cargo build --release --lib \
--features ocr,rendering,signatures,barcodes,tsa-client,system-fonts
# 2. test + run the example
cd zig
LD_LIBRARY_PATH="$PWD/../target/release" \
zig build test \
-DPDF_OXIDE_INCLUDE_DIR="$PWD/../include" \
-DPDF_OXIDE_LIB_DIR="$PWD/../target/release"
LD_LIBRARY_PATH="$PWD/../target/release" \
zig build example \
-DPDF_OXIDE_INCLUDE_DIR="$PWD/../include" \
-DPDF_OXIDE_LIB_DIR="$PWD/../target/release"
In Ihrem eigenen Code importieren Sie das Modul und legen direkt los:
const pdf_oxide = @import("pdf_oxide");
Ein PDF öffnen
Öffnen Sie eine Datei mit Document.open (oder Document.openFromBytes für Daten im Speicher) und prüfen Sie deren Metadaten. Jedes Handle besitzt C-Ressourcen, kombinieren Sie es daher mit defer doc.deinit().
const std = @import("std");
const pdf_oxide = @import("pdf_oxide");
pub fn main() !void {
const a = std.heap.page_allocator;
var doc = try pdf_oxide.Document.open("research-paper.pdf");
defer doc.deinit();
std.debug.print("pages: {d}\n", .{try doc.pageCount()});
const v = doc.version();
std.debug.print("version: {d}.{d}\n", .{ v.major, v.minor });
std.debug.print("encrypted: {}\n", .{doc.isEncrypted()});
}
Textextraktion
extractText gibt den Text einer einzelnen Seite zurück (0-basiert). Das Ergebnis gehört dem Allocator, den Sie übergeben, geben Sie es also frei, wenn Sie fertig sind.
const a = std.heap.page_allocator;
var doc = try pdf_oxide.Document.open("report.pdf");
defer doc.deinit();
const text = try doc.extractText(a, 0);
defer a.free(text);
std.debug.print("{s}\n", .{text});
Die Varianten für das gesamte Dokument extrahieren jede Seite auf einmal:
const all_text = try doc.toPlainTextAll(a);
defer a.free(all_text);
std.debug.print("{s}\n", .{all_text});
Markdown- & HTML-Konvertierung
Konvertieren Sie eine einzelne Seite oder das gesamte Dokument nach Markdown oder HTML. Jede Funktion gibt einen Allocator-eigenen Slice zurück.
const md = try doc.toMarkdown(a, 0);
defer a.free(md);
std.debug.print("{s}\n", .{md});
const md_all = try doc.toMarkdownAll(a);
defer a.free(md_all);
const html = try doc.toHtml(a, 0);
defer a.free(html);
Extraktion auf Wortebene
extractWords gibt einen Slice von Word-Structs mit Text, Bounding Box, Schriftart und Fett-Flag zurück. Geben Sie den gesamten Slice mit dem passenden Helfer freeWords frei — er gibt die einzelnen Wort-Strings und den zugrunde liegenden Slice frei.
const words = try doc.extractWords(a, 0);
defer pdf_oxide.Document.freeWords(a, words);
for (words) |w| {
std.debug.print("'{s}' at ({d:.1}, {d:.1}) font={s} size={d:.1} bold={}\n", .{
w.text, w.bbox.x, w.bbox.y, w.fontName, w.fontSize, w.bold,
});
}
Word-Felder:
| Feld | Typ | Beschreibung |
|---|---|---|
text |
[]u8 |
Worttext (Allocator-eigen) |
bbox |
Bbox |
{ x, y, width, height } in Punkten |
fontName |
[]u8 |
PostScript-Schriftname |
fontSize |
f32 |
Schriftgröße in Punkten |
bold |
bool |
Ob der Lauf fett ist |
Dasselbe Muster liefert Ihnen Zeichen und Zeilen:
const chars = try doc.extractChars(a, 0);
defer pdf_oxide.Document.freeChars(a, chars);
const lines = try doc.extractTextLines(a, 0);
defer pdf_oxide.Document.freeTextLines(a, lines);
Suche
search durchsucht eine einzelne Seite; searchAll durchsucht jede Seite. Beide nehmen einen NUL-terminierten Suchbegriff und ein case_sensitive-Flag entgegen und geben einen Slice von SearchResult zurück.
const hits = try doc.searchAll(a, "configuration", false);
defer pdf_oxide.Document.freeSearchResults(a, hits);
for (hits) |hit| {
std.debug.print("page {d}: '{s}' at ({d:.0}, {d:.0})\n", .{
hit.page, hit.text, hit.bbox.x, hit.bbox.y,
});
}
Um die Suche auf eine einzelne Seite zu beschränken, verwenden Sie search mit dem Seitenindex:
const page_hits = try doc.search(a, 0, "Alpha", false);
defer pdf_oxide.Document.freeSearchResults(a, page_hits);
Ein PDF erstellen
Der Typ Pdf erstellt Dokumente aus Markdown, HTML oder Klartext. toBytes serialisiert in den Speicher; save schreibt auf die Festplatte.
const a = std.heap.page_allocator;
var pdf = try pdf_oxide.Pdf.fromMarkdown("# Hello\n\nThis is a **Zig** PDF.\n");
defer pdf.deinit();
// Serialize to memory...
const bytes = try pdf.toBytes(a);
defer a.free(bytes);
// ...or write straight to disk.
try pdf.save("output.pdf");
Sie können ein frisch erstelltes PDF direkt wieder durch den Extraktor laufen lassen:
var pdf = try pdf_oxide.Pdf.fromHtml("<h1>Invoice</h1><p>Amount: $42</p>");
defer pdf.deinit();
const bytes = try pdf.toBytes(a);
defer a.free(bytes);
var doc = try pdf_oxide.Document.openFromBytes(bytes);
defer doc.deinit();
const text = try doc.extractText(a, 0);
defer a.free(text);
std.debug.print("{s}\n", .{text});
Fehlerbehandlung
Fehlbare Aufrufe geben Error!T zurück, wobei Error für error{ PdfOxide, OutOfMemory } steht. Da Zig-Fehlerwerte keine Nutzlast tragen können, wird der zugrunde liegende C-ABI-Code über lastErrorCode() bereitgestellt — lesen Sie ihn unmittelbar nach dem Abfangen von error.PdfOxide.
const text = doc.extractText(a, 99) catch |err| switch (err) {
error.PdfOxide => {
std.debug.print("pdf_oxide error code: {d}\n", .{pdf_oxide.lastErrorCode()});
return;
},
error.OutOfMemory => return err,
};
defer a.free(text);
Nächste Schritte
- Erste Schritte mit Rust — der native Kern, auf dem PDF Oxide aufbaut
- Erste Schritte mit Python — PDF Oxide aus Python verwenden
- Textextraktion — detaillierte Extraktionsoptionen und Rezepte
- PDF-Erstellung — erweiterte Erstellung mit Metadaten und Verschlüsselung