PDF/A バリデーション
PDF/A (ISO 19005) は電子ドキュメントの長期保存のための国際標準です。 PDF Oxide はすべての主要な PDF/A レベルを検証し、非準拠ドキュメントを準拠に向けて変換できます。
サポートされるレベル
| Level | Standard | Structure | Unicode | Transparency | Embedded Files |
|---|---|---|---|---|---|
| 1a | ISO 19005-1 | Required | Required | No | No |
| 1b | ISO 19005-1 | No | No | No | No |
| 2a | ISO 19005-2 | Required | Required | Yes | No |
| 2b | ISO 19005-2 | No | No | Yes | No |
| 2u | ISO 19005-2 | No | Required | Yes | No |
| 3a | ISO 19005-3 | Required | Required | Yes | Yes |
| 3b | ISO 19005-3 | No | No | Yes | Yes |
| 3u | ISO 19005-3 | No | Required | Yes | Yes |
レベル「a」(アクセシブル)はタグ付き構造ツリーとUnicode文字マッピングが必要です。レベル「b」(基本)は視覚的再現性のみ必要です。レベル「u」(Unicode)は完全な構造ツリーなしでUnicodeテキストマッピングが必要です。
簡易バリデーション
ワンコールチェック用の便利関数を使用します:
from pdf_oxide import PdfDocument
doc = PdfDocument("document.pdf")
result = doc.validate_pdf_a("2b")
print(f"Valid: {result.valid}")
print(f"Level: {result.level}")
for error in result.errors:
print(f" Error: {error}")
const doc = new WasmPdfDocument(bytes);
const result = doc.validatePdfA("2b");
console.log(`Valid: ${result.valid}`);
console.log(`Errors: ${result.errors.length}`);
doc.free();
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{validate_pdf_a, PdfALevel};
let mut doc = PdfDocument::open("archive.pdf")?;
let result = validate_pdf_a(&mut doc, PdfALevel::A1b)?;
if result.has_errors() {
println!("Not PDF/A-1b compliant:");
for error in &result.errors {
println!(" [{}] {} (clause {})",
error.code, error.message,
error.clause.as_deref().unwrap_or("n/a"));
}
} else {
println!("Document is PDF/A-1b compliant");
}
バリデータ API
PdfAValidator はきめ細かい制御のためのビルダーパターンを提供します:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{PdfAValidator, PdfALevel};
let mut doc = PdfDocument::open("report.pdf")?;
let result = PdfAValidator::new()
.stop_on_first_error(false)
.include_warnings(true)
.validate(&mut doc, PdfALevel::A2b)?;
println!("Errors: {}", result.errors.len());
println!("Warnings: {}", result.warnings.len());
個別チェック
Run individual validation categories instead of the full suite:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{PdfAValidator, PdfALevel};
let mut doc = PdfDocument::open("report.pdf")?;
let validator = PdfAValidator::new();
// Check only metadata
let result = validator.check_metadata(&mut doc, PdfALevel::A1b)?;
// Check only fonts
let result = validator.check_fonts(&mut doc, PdfALevel::A1b)?;
// Check only color spaces
let result = validator.check_colors(&mut doc, PdfALevel::A1b)?;
// Check only transparency
let result = validator.check_transparency(&mut doc, PdfALevel::A2b)?;
// Check only structure tags
let result = validator.check_structure(&mut doc, PdfALevel::A1a)?;
スタンドアロンバリデータ
Each validation category is also available as a standalone function for maximum flexibility:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::validators::*;
use pdf_oxide::compliance::{PdfALevel, ValidationResult};
let mut doc = PdfDocument::open("document.pdf")?;
let mut result = ValidationResult::new(PdfALevel::A1b);
// Run each validator independently
validate_xmp_metadata(&mut doc, PdfALevel::A1b, &mut result)?;
validate_fonts(&mut doc, PdfALevel::A1b, &mut result)?;
validate_colors(&mut doc, PdfALevel::A1b, &mut result)?;
validate_encryption(&mut doc, PdfALevel::A1b, &mut result)?;
validate_transparency(&mut doc, PdfALevel::A1b, &mut result)?;
validate_structure(&mut doc, PdfALevel::A1b, &mut result)?;
validate_javascript(&mut doc, PdfALevel::A1b, &mut result)?;
validate_embedded_files(&mut doc, PdfALevel::A1b, &mut result)?;
validate_annotations(&mut doc, PdfALevel::A1b, &mut result)?;
println!("Total errors: {}", result.errors.len());
バリデータ一覧
| Function | What It Checks |
|---|---|
validate_xmp_metadata() |
XMPストリームが存在, pdfaid:part and pdfaid:conformance entries present, metadata consistency |
validate_fonts() |
すべてのフォントが埋め込み済み, glyph widths present, Unicodeマッピングが利用可能 (for level “a” and “u”) |
validate_colors() |
出力インテントなしのデバイス依存色演算子(rg、RG、k、K、g、G)なし |
validate_encryption() |
PDF/Aドキュメントで暗号化不可 |
validate_transparency() |
PDF/A-1で透明度不可、PDF/A-2以降は許可 |
validate_structure() |
有効なロールマッピング付きタグ構造ツリーが存在 (required for level “a”) |
validate_javascript() |
JavaScriptアクション/トリガーなし |
validate_embedded_files() |
PDF/A-1またはPDF/A-2では不可、PDF/A-3は各ファイル仕様に AFRelationship キーが必要 |
validate_annotations() |
注釈タイプs restricted per the relevant ISO 19005 part |
ValidationResult
The ValidationResult struct contains the full outcome of a validation run:
pub struct ValidationResult {
pub level: PdfALevel,
pub errors: Vec<ComplianceError>,
pub warnings: Vec<ComplianceWarning>,
pub stats: ValidationStats,
}
| Field | Type | 説明 |
|---|---|---|
level |
PdfALevel |
対象準拠レベル |
errors |
Vec<ComplianceError> |
準拠を妨げるブロッキング違反 |
warnings |
Vec<ComplianceWarning> |
品質に影響する可能性のある問題 |
stats |
ValidationStats |
チェックされたページ、フォント、オブジェクト数 |
ComplianceError
pub struct ComplianceError {
pub code: ErrorCode,
pub message: String,
pub location: Option<String>,
pub clause: Option<String>,
}
code フィールドは MissingXmpMetadata、FontNotEmbedded、DeviceDependentColor、EncryptionPresent、TransparencyNotAllowed、MissingStructureTree、JavaScriptPresent、InvalidEmbeddedFile などのカテゴリを持つ ErrorCode 列挙型を使用します。
ComplianceWarning
pub struct ComplianceWarning {
pub code: WarningCode,
pub message: String,
pub location: Option<String>,
}
PDF/A 変換
Convert a non-compliant document toward PDF/A compliance:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{convert_to_pdf_a, PdfALevel};
let mut doc = PdfDocument::open("input.pdf")?;
let result = convert_to_pdf_a(&mut doc, PdfALevel::A1b)?;
println!("実行された変換アクション:");
for action in &result.actions {
println!(" - {}: {}", action.action_type, action.description);
}
if result.remaining_errors.is_empty() {
println!("ドキュメントはPDF/A-1b準拠になりました");
} else {
println!("{} 問題は自動的に解決できませんでした",
result.remaining_errors.len());
}
変換設定
Fine-tune the conversion process:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{PdfAConverter, PdfALevel, ConversionConfig};
let mut doc = PdfDocument::open("input.pdf")?;
let config = ConversionConfig::new()
.embed_fonts(true)
.remove_javascript(true)
.flatten_transparency(true)
.add_structure(true);
let result = PdfAConverter::new(PdfALevel::A2b)
.with_config(config)
.convert(&mut doc)?;
コンバータは自動的に以下のアクションを実行します:
- XMPメタデータ注入 –
pdfaid:partとpdfaid:conformanceエントリを追加 - フォント埋め込み – 参照されているが埋め込まれていないフォントを埋め込み
- JavaScript除去 – JavaScriptアクションとトリガーを除去
- 透明度フラット化 – 透明要素を不透明にレンダリング(PDF/A-1のみ)
- ICCプロファイル変換 – デバイス依存色をICCベースの色空間に変換
- 構造タグ付け – 基本構造タグを追加(レベル「a」ターゲット用)
ワークフロー:検証、修正、再検証
典型的なアーカイブワークフローはバリデーション、自動変換の試行、再バリデーションを行います:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{validate_pdf_a, convert_to_pdf_a, PdfALevel};
let level = PdfALevel::A2b;
let mut doc = PdfDocument::open("input.pdf")?;
// Step 1: Initial validation
let result = validate_pdf_a(&mut doc, level)?;
if !result.has_errors() {
println!("既に準拠");
return Ok(());
}
println!("{} エラーが見つかりました、変換を試行中...", result.errors.len());
// Step 2: Automatic conversion
let conversion = convert_to_pdf_a(&mut doc, level)?;
println!("{} アクション実行済み", conversion.actions.len());
// Step 3: Re-validate
let result = validate_pdf_a(&mut doc, level)?;
if result.has_errors() {
println!("{} 変換後もエラーが残存:", result.errors.len());
for e in &result.errors {
println!(" {} -- {}", e.code, e.message);
}
} else {
println!("ドキュメントはPDF/A-2b準拠になりました");
}
PdfALevel Methods
PdfALevel 列挙型にはレベルの機能を問い合わせるヘルパーメソッドが含まれます:
| Method | Return | 説明 |
|---|---|---|
part() |
PdfAPart |
ISO 19005パート(Part1、Part2、Part3) |
conformance() |
char |
適合レベル文字(‘a’、‘b’、‘u’) |
requires_structure() |
bool |
タグ付き構造ツリーが必須か |
requires_unicode() |
bool |
Unicodeマッピングが必須か |
allows_transparency() |
bool |
透明度が許可されるか |
allows_jpeg2000() |
bool |
JPEG 2000画像が許可されるか |
allows_embedded_files() |
bool |
ファイル添付が許可されるか |
xmp_part() |
&str |
XMP pdfaid:part 値 |
xmp_conformance() |
&str |
XMP pdfaid:conformance 値 |
from_xmp(part, conformance) |
Option<Self> |
XMPメタデータ値からレベルをパース |
次のステップ
- PDF/UA Accessibility – アクセシビリティバリデーション
- PDF/X Print Production – 印刷プロダクションバリデーション
- API Reference – 完全なRust API