PDF/X Druckproduktion
PDF/X (ISO 15930) ist der Standard für den zuverlässigen Austausch druckfertiger PDF-Dateien. PDF Oxide validiert alle wichtigen PDF/X-Stufen und prüft Seitenrahmen, Farbräume, Transparenz, ICC-Profile und Output Intents.
Abdeckung in den Bindings. Die PDF/X-Validierung steht in Python (
doc.validate_pdf_x(level)), Rust (validate_pdf_x+PdfXValidator-Builder) und Go (doc.ValidatePdfX(level)) zur Verfügung. WASM und C# stellen die PDF/X-Validierung noch nicht bereit — nutzen Sie die Rust-CLI (pdf-oxide validate --pdfx 4 doc.pdf) oder rufen Sie sie über eine der unterstützten Bindings auf.
Unterstützte Stufen
| Stufe | Standard | Transparenz | RGB | Ebenen | Externes ICC | Externe Grafiken |
|---|---|---|---|---|---|---|
| X-1a:2001 | ISO 15930-1 | Nein | Nein | Nein | Nein | Nein |
| X-1a:2003 | ISO 15930-4 | Nein | Nein | Nein | Nein | Nein |
| X-3:2002 | ISO 15930-3 | Nein | Ja | Nein | Nein | Nein |
| X-3:2003 | ISO 15930-6 | Nein | Ja | Nein | Nein | Nein |
| X-4 | ISO 15930-7 | Ja | Ja | Ja | Nein | Nein |
| X-4p | ISO 15930-7 | Ja | Ja | Ja | Ja | Nein |
| X-5g | ISO 15930-8 | Ja | Ja | Ja | Nein | Ja |
| X-5n | ISO 15930-8 | Ja | Ja | Ja | Nein | Ja |
| X-5pg | ISO 15930-8 | Ja | Ja | Ja | Ja | Ja |
| X-6 | ISO 15930-9 | Ja | Ja | Ja | Nein | Nein |
| X-6n | ISO 15930-9 | Ja | Ja | Ja | Nein | Ja |
| X-6p | ISO 15930-9 | Ja | Ja | Ja | Ja | Nein |
PDF/X-1a ist am restriktivsten: nur CMYK, keine Transparenz, keine Ebenen. PDF/X-4 ist die am häufigsten verwendete moderne Stufe und erlaubt Transparenz und RGB mit ICC-Profilen.
Schnelle Validierung
from pdf_oxide import PdfDocument
doc = PdfDocument("document.pdf")
result = doc.validate_pdf_x("4")
print(f"Valid: {result.valid}")
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::pdf_x::{validate_pdf_x, PdfXLevel};
let mut doc = PdfDocument::open("print-ready.pdf")?;
let result = validate_pdf_x(&mut doc, PdfXLevel::X4)?;
if result.has_errors() {
println!("Not PDF/X-4 compliant ({} errors):", result.errors.len());
for error in &result.errors {
println!(" [{}] {} (clause {})",
error.code, error.message,
error.clause.as_deref().unwrap_or("n/a"));
}
} else {
println!("Document is PDF/X-4 compliant");
}
doc, _ := pdfoxide.Open("print-ready.pdf")
defer doc.Close()
// Level encoding: 0 = X-1a:2001, 1 = X-1a:2003, 2 = X-3:2002, 3 = X-3:2003, 4 = X-4, ...
valid, errs, err := doc.ValidatePdfX(4) // PDF/X-4
if err != nil { log.Fatal(err) }
if valid {
fmt.Println("Document is PDF/X-4 compliant")
} else {
fmt.Printf("Not PDF/X-4 compliant (%d errors):\n", len(errs))
for _, e := range errs {
fmt.Printf(" %s\n", e)
}
}
Validator-API
Der PdfXValidator-Builder konfiguriert den Validierungslauf:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::pdf_x::{PdfXValidator, PdfXLevel};
let mut doc = PdfDocument::open("artwork.pdf")?;
let result = PdfXValidator::new(PdfXLevel::X1a2001)
.stop_on_first_error(false)
.include_warnings(true)
.validate(&mut doc)?;
println!("Errors: {}", result.errors.len());
println!("Warnings: {}", result.warnings.len());
println!("Total issues: {}", result.total_issues());
Was geprüft wird
XMP-Identifikation
Der Validator stellt sicher, dass die XMP-Metadaten die korrekte PDF/X-Version deklarieren:
pdfxid:GTS_PDFXVersionmuss mit der Zielstufe übereinstimmen- Die deklarierte Version wird mit dem
gts_pdfx_version()der Zielstufe verglichen
Beziehungen der Seitenrahmen
PDF/X verlangt eine bestimmte Verschachtelung der Seitenrahmen:
TrimBox <= BleedBox <= MediaBox
ArtBox <= MediaBox
Der Validator prüft jede Seite, um sicherzustellen, dass:
- die TrimBox vorhanden ist (von allen PDF/X-Stufen gefordert)
- die TrimBox innerhalb der BleedBox liegt (sofern die BleedBox definiert ist)
- die BleedBox innerhalb der MediaBox liegt
- die ArtBox innerhalb der MediaBox liegt (sofern die ArtBox definiert ist)
- eine Toleranz von 0,01 Punkt für Gleitkomma-Rundungen gilt
Transparenzerkennung
Für PDF/X-1a und PDF/X-3 ist keine Transparenz zulässig. Der Validator prüft:
- SMask in ExtGState-Dictionaries (muss
/Noneoder nicht vorhanden sein) - CA (Kontur-Deckkraft) muss gleich 1.0 sein
- ca (Füll-Deckkraft) muss gleich 1.0 sein
- BM (Mischmodus) muss
NormaloderCompatiblesein
PDF/X-4 und spätere Stufen erlauben Transparenz.
Farbraum-Validierung
Der Validator prüft die Verwendung geräteabhängiger Farben:
- DeviceRGB ist in PDF/X-1a nicht zulässig (nur CMYK)
- DeviceRGB, DeviceCMYK und DeviceGray, die ohne Output Intent verwendet werden, lösen in strengeren Stufen Fehler aus
- Die Farboperatoren
rg,RG,k,K,g,Gin den Inhaltsströmen der Seiten werden durchsucht
ICC-Profil-Validierung
Für ICCBased-Farbräume prüft der Validator:
- Der Profilstrom enthält den erforderlichen Eintrag
/N(Anzahl der Komponenten) - Der Wert von
/Nstimmt mit der erwarteten Dimension des Farbraums überein (1 für Grau, 3 für RGB, 4 für CMYK) - Die Profildaten sind vorhanden und nicht leer
Output Intent
PDF/X verlangt einen Output Intent, der die beabsichtigten Druckbedingungen beschreibt:
- Das Array
/OutputIntentsmuss im Dokumentkatalog vorhanden sein - Mindestens ein Eintrag mit dem Subtyp
GTS_PDFXist erforderlich - Der Output Intent sollte auf ein ICC-Profil oder eine registrierte Druckbedingung verweisen
XValidationResult
pub struct XValidationResult {
pub level: PdfXLevel,
pub errors: Vec<XComplianceError>,
pub warnings: Vec<XComplianceError>,
pub stats: XValidationStats,
}
XComplianceError
pub struct XComplianceError {
pub code: XErrorCode,
pub message: String,
pub severity: XSeverity,
pub page: Option<usize>,
pub object_id: Option<u32>,
pub clause: Option<String>,
}
Fehler enthalten die Seitenzahl und die Objekt-ID, an der der Verstoß gefunden wurde, sodass sich Probleme in der Quelldatei mühelos lokalisieren und beheben lassen.
XErrorCode-Kategorien
Das Enum XErrorCode enthält über 40 spezifische Fehlercodes, nach Kategorie geordnet:
Metadaten: MissingOutputIntent, InvalidGtsPdfxVersion, MissingXmpIdentification
Seitenrahmen: MissingTrimBox, TrimBoxOutsideBleedBox, BleedBoxOutsideMediaBox, ArtBoxOutsideMediaBox
Transparenz: TransparencyNotAllowed, InvalidBlendMode, InvalidSMask, InvalidOpacity
Farbe: DeviceRgbNotAllowed, DeviceDependentColorWithoutIntent, InvalidIccProfile, MissingIccComponents
Inhalt: ExternalContentNotAllowed, EncryptionNotAllowed, JavaScriptNotAllowed
PdfXLevel-Methoden
| Methode | Rückgabe | Beschreibung |
|---|---|---|
iso_standard() |
&str |
ISO-Standardnummer (z. B. "ISO 15930-7") |
required_pdf_version() |
&str |
Mindest-PDF-Version (z. B. "1.6") |
allows_transparency() |
bool |
Ob Transparenzgruppen zulässig sind |
allows_rgb() |
bool |
Ob der RGB-Farbraum zulässig ist |
allows_layers() |
bool |
Ob Gruppen optionaler Inhalte zulässig sind |
allows_external_icc() |
bool |
Ob externe ICC-Profile zulässig sind |
allows_external_graphics() |
bool |
Ob Verweise auf externe Grafiken zulässig sind |
gts_pdfx_version() |
&str |
Erwarteter GTS_PDFXVersion-Wert |
xmp_version() |
&str |
Erwarteter XMP-Versionsbezeichner |
from_gts_version(version) |
Option<Self> |
Stufe aus einer GTS-Versionszeichenfolge parsen |
Praxisbeispiel: Druckvorstufenprüfung
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::pdf_x::{validate_pdf_x, PdfXLevel, XSeverity};
let mut doc = PdfDocument::open("magazine-cover.pdf")?;
let result = validate_pdf_x(&mut doc, PdfXLevel::X4)?;
println!("=== PDF/X-4 Prepress Report ===");
println!("Status: {}", if result.has_errors() { "REJECT" } else { "ACCEPT" });
// Group errors by severity
let critical: Vec<_> = result.errors.iter()
.filter(|e| e.is_error())
.collect();
let advisory: Vec<_> = result.warnings.iter().collect();
if !critical.is_empty() {
println!("\nCritical ({}):", critical.len());
for e in &critical {
let page_str = e.page
.map(|p| format!("page {}", p + 1))
.unwrap_or_else(|| "document".into());
println!(" [{}] {} ({})", e.code, e.message, page_str);
}
}
if !advisory.is_empty() {
println!("\nAdvisory ({}):", advisory.len());
for w in &advisory {
println!(" [{}] {}", w.code, w.message);
}
}
Nächste Schritte
- PDF/A-Validierung – Konformität für die Archivierung
- PDF/UA-Barrierefreiheit – Validierung der Barrierefreiheit
- API-Referenz – vollständige Rust-API