Поліграфічне виробництво PDF/X
PDF/X (ISO 15930) — це стандарт для надійного обміну готовими до друку PDF-файлами. PDF Oxide перевіряє всі основні рівні PDF/X, контролюючи рамки сторінки, колірні простори, прозорість, ICC-профілі та умови виводу.
Підтримка у прив’язках. Перевірка PDF/X доступна у Python (
doc.validate_pdf_x(level)), Rust (validate_pdf_x+ білдерPdfXValidator) та Go (doc.ValidatePdfX(level)). WASM і C# поки що не надають перевірку PDF/X — скористайтеся Rust CLI (pdf-oxide validate --pdfx 4 doc.pdf) або викликайте через одну з підтримуваних прив’язок.
Підтримувані рівні
| Рівень | Стандарт | Прозорість | RGB | Шари | Зовнішній ICC | Зовнішня графіка |
|---|---|---|---|---|---|---|
| X-1a:2001 | ISO 15930-1 | Ні | Ні | Ні | Ні | Ні |
| X-1a:2003 | ISO 15930-4 | Ні | Ні | Ні | Ні | Ні |
| X-3:2002 | ISO 15930-3 | Ні | Так | Ні | Ні | Ні |
| X-3:2003 | ISO 15930-6 | Ні | Так | Ні | Ні | Ні |
| X-4 | ISO 15930-7 | Так | Так | Так | Ні | Ні |
| X-4p | ISO 15930-7 | Так | Так | Так | Так | Ні |
| X-5g | ISO 15930-8 | Так | Так | Так | Ні | Так |
| X-5n | ISO 15930-8 | Так | Так | Так | Ні | Так |
| X-5pg | ISO 15930-8 | Так | Так | Так | Так | Так |
| X-6 | ISO 15930-9 | Так | Так | Так | Ні | Ні |
| X-6n | ISO 15930-9 | Так | Так | Так | Ні | Так |
| X-6p | ISO 15930-9 | Так | Так | Так | Так | Ні |
PDF/X-1a — найсуворіший рівень: лише CMYK, без прозорості та без шарів. PDF/X-4 — найпоширеніший сучасний рівень, що допускає прозорість і RGB з ICC-профілями.
Швидка перевірка
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)
}
}
API валідатора
Білдер PdfXValidator налаштовує запуск перевірки:
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());
Що перевіряється
Ідентифікація XMP
Валідатор підтверджує, що метадані XMP оголошують правильну версію PDF/X:
pdfxid:GTS_PDFXVersionмає відповідати цільовому рівню- Оголошена версія порівнюється зі значенням
gts_pdfx_version()для цільового рівня
Співвідношення рамок сторінки
PDF/X вимагає певного вкладення рамок сторінки:
TrimBox <= BleedBox <= MediaBox
ArtBox <= MediaBox
Валідатор перевіряє кожну сторінку, щоб переконатися, що:
- TrimBox присутній (вимагається на всіх рівнях PDF/X)
- TrimBox міститься всередині BleedBox (якщо BleedBox визначено)
- BleedBox міститься всередині MediaBox
- ArtBox міститься всередині MediaBox (якщо ArtBox визначено)
- Допуск 0,01 пункту для округлення чисел з плаваючою комою
Виявлення прозорості
Для PDF/X-1a та PDF/X-3 прозорість не дозволяється. Валідатор перевіряє:
- SMask у словниках ExtGState (має бути
/Noneабо відсутнім) - CA (непрозорість обведення) має дорівнювати 1.0
- ca (непрозорість заливки) має дорівнювати 1.0
- BM (режим змішування) має бути
NormalабоCompatible
PDF/X-4 та пізніші рівні дозволяють прозорість.
Перевірка колірного простору
Валідатор перевіряє використання апаратно-залежних кольорів:
- DeviceRGB не дозволяється у PDF/X-1a (лише CMYK)
- DeviceRGB, DeviceCMYK та DeviceGray, використані без умови виводу, спричиняють помилки на суворіших рівнях
- Скануються колірні оператори
rg,RG,k,K,g,Gу потоках вмісту сторінок
Перевірка ICC-профілю
Для колірних просторів ICCBased валідатор перевіряє:
- Потік профілю містить обов’язковий запис
/N(кількість компонентів) - Значення
/Nвідповідає очікуваній розмірності колірного простору (1 для сірого, 3 для RGB, 4 для CMYK) - Дані профілю присутні й не порожні
Умова виводу
PDF/X вимагає умови виводу, що описує передбачувані умови друку:
- Масив
/OutputIntentsмає бути присутнім у каталозі документа - Потрібен щонайменше один запис із підтипом
GTS_PDFX - Умова виводу має посилатися на ICC-профіль або зареєстровану умову друку
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>,
}
Помилки містять номер сторінки та ідентифікатор об’єкта, де було виявлено порушення, що спрощує пошук і виправлення проблем у вихідному файлі.
Категорії XErrorCode
Перелік XErrorCode містить понад 40 конкретних кодів помилок, згрупованих за категоріями:
Метадані: MissingOutputIntent, InvalidGtsPdfxVersion, MissingXmpIdentification
Рамки сторінки: MissingTrimBox, TrimBoxOutsideBleedBox, BleedBoxOutsideMediaBox, ArtBoxOutsideMediaBox
Прозорість: TransparencyNotAllowed, InvalidBlendMode, InvalidSMask, InvalidOpacity
Колір: DeviceRgbNotAllowed, DeviceDependentColorWithoutIntent, InvalidIccProfile, MissingIccComponents
Вміст: ExternalContentNotAllowed, EncryptionNotAllowed, JavaScriptNotAllowed
Методи PdfXLevel
| Метод | Повертає | Опис |
|---|---|---|
iso_standard() |
&str |
Номер стандарту ISO (наприклад, "ISO 15930-7") |
required_pdf_version() |
&str |
Мінімальна версія PDF (наприклад, "1.6") |
allows_transparency() |
bool |
Чи дозволені групи прозорості |
allows_rgb() |
bool |
Чи дозволений колірний простір RGB |
allows_layers() |
bool |
Чи дозволені групи необов’язкового вмісту |
allows_external_icc() |
bool |
Чи дозволені зовнішні ICC-профілі |
allows_external_graphics() |
bool |
Чи дозволені посилання на зовнішню графіку |
gts_pdfx_version() |
&str |
Очікуване значення GTS_PDFXVersion |
xmp_version() |
&str |
Очікуваний ідентифікатор версії XMP |
from_gts_version(version) |
Option<Self> |
Розбір рівня з рядка версії GTS |
Практичний приклад: переддрукарська перевірка
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);
}
}
Подальші кроки
- Перевірка PDF/A – відповідність вимогам архівування
- Доступність PDF/UA – перевірка доступності
- Довідник API – повний API на Rust