Skip to content

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_PDFXVersion muss 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 /None oder nicht vorhanden sein)
  • CA (Kontur-Deckkraft) muss gleich 1.0 sein
  • ca (Füll-Deckkraft) muss gleich 1.0 sein
  • BM (Mischmodus) muss Normal oder Compatible sein

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, G in 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 /N stimmt 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 /OutputIntents muss im Dokumentkatalog vorhanden sein
  • Mindestens ein Eintrag mit dem Subtyp GTS_PDFX ist 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