PDF/X 印刷生产
PDF/X(ISO 15930)是印刷就绪 PDF 文件可靠交换的标准。PDF Oxide 验证所有主要 PDF/X 级别,检查页面框、色彩空间、透明度、ICC 配置文件和输出意图。
支持的级别
| 级别 | 标准 | 透明度 | RGB | Layers | 外部 ICC | 外部图形 |
|---|---|---|---|---|---|---|
| X-1a:2001 | ISO 15930-1 | No | No | No | No | No |
| X-1a:2003 | ISO 15930-4 | No | No | No | No | No |
| X-3:2002 | ISO 15930-3 | No | Yes | No | No | No |
| X-3:2003 | ISO 15930-6 | No | Yes | No | No | No |
| X-4 | ISO 15930-7 | Yes | Yes | Yes | No | No |
| X-4p | ISO 15930-7 | Yes | Yes | Yes | Yes | No |
| X-5g | ISO 15930-8 | Yes | Yes | Yes | No | Yes |
| X-5n | ISO 15930-8 | Yes | Yes | Yes | No | Yes |
| X-5pg | ISO 15930-8 | Yes | Yes | Yes | Yes | Yes |
| X-6 | ISO 15930-9 | Yes | Yes | Yes | No | No |
| X-6n | ISO 15930-9 | Yes | Yes | Yes | No | Yes |
| X-6p | ISO 15930-9 | Yes | Yes | Yes | Yes | No |
PDF/X-1a 是最严格的:仅限 CMYK,不允许透明度和图层。PDF/X-4 是最常用的现代级别,允许透明度和带有 ICC 配置文件的 RGB。
快速验证
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, PdfX级别};
let mut doc = PdfDocument::open("print-ready.pdf")?;
let result = validate_pdf_x(&mut doc, PdfX级别::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");
}
验证器 API
PdfXValidator 构建器用于配置验证运行:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::pdf_x::{PdfXValidator, PdfX级别};
let mut doc = PdfDocument::open("artwork.pdf")?;
let result = PdfXValidator::new(PdfX级别::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,不允许透明度。验证器检查:
- ExtGState 字典中的 SMask(必须为
/None或不存在) - CA (stroke opacity) must equal 1.0
- ca (fill opacity) must equal 1.0
- BM(混合模式)必须为
Normal或Compatible
PDF/X-4 及以上级别允许透明度。
色彩空间验证
验证器检查设备相关的颜色使用:
- DeviceRGB 在 PDF/X-1a 中不允许(仅限 CMYK)
- 在更严格的级别中,不带输出意图使用 DeviceRGB、DeviceCMYK 和 DeviceGray 会触发错误
- Color operators
rg,RG,k,K,g,Gin page 内容流s are scanned
ICC 配置文件验证
对于 ICCBased 色彩空间,验证器检查:
- 配置文件流包含必需的
/N(组件数)条目 - The
/Nvalue matches the expected 色彩空间 dimension (1 for gray, 3 for RGB, 4 for CMYK) - 配置文件数据存在且非空
输出意图
PDF/X 要求包含描述预期印刷条件的输出意图:
- 文档目录中必须存在
/OutputIntents数组 - 至少需要一个子类型为
GTS_PDFX的条目 - 输出意图应引用 ICC 配置文件或注册的印刷条件
XValidationResult
pub struct XValidationResult {
pub level: PdfX级别,
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>,
}
错误信息包含发现违规的页码和对象 ID,便于在源文件中定位和修复问题。
XErrorCode Categories
XErrorCode 枚举包含 40 多个按类别组织的特定错误码:
元数据:MissingOutputIntent、InvalidGtsPdfxVersion、MissingXmpIdentification
页面框:MissingTrimBox、TrimBoxOutsideBleedBox、BleedBoxOutsideMediaBox、ArtBoxOutsideMediaBox
透明度:透明度NotAllowed、InvalidBlendMode、InvalidSMask、InvalidOpacity
颜色:DeviceRgbNotAllowed、DeviceDependentColorWithoutIntent、InvalidIccProfile、MissingIccComponents
内容:ExternalContentNotAllowed、加密NotAllowed、JavaScriptNotAllowed
PdfXLevel 方法
| 方法 | 返回值 | 描述 |
|---|---|---|
iso_standard() |
&str |
ISO standard number (e.g., "ISO 15930-7") |
required_pdf_version() |
&str |
Minimum PDF version (e.g., "1.6") |
allows_透明度() |
bool |
Whether 透明度 groups are permitted |
allows_rgb() |
bool |
Whether RGB color space is permitted |
allows_layers() |
bool |
Whether optional content groups are permitted |
allows_external_icc() |
bool |
Whether external ICC profiles are permitted |
allows_external_graphics() |
bool |
Whether external graphics references are permitted |
gts_pdfx_version() |
&str |
Expected GTS_PDFXVersion value |
xmp_version() |
&str |
Expected XMP version identifier |
from_gts_version(version) |
Option<Self> |
Parse level from a GTS version string |
实际示例:印前检查
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::pdf_x::{validate_pdf_x, PdfX级别, XSeverity};
let mut doc = PdfDocument::open("magazine-cover.pdf")?;
let result = validate_pdf_x(&mut doc, PdfX级别::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 参考 – 完整 Rust API