Skip to content

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() 出力インテントなしのデバイス依存色演算子(rgRGkKgG)なし
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 フィールドは MissingXmpMetadataFontNotEmbeddedDeviceDependentColorEncryptionPresentTransparencyNotAllowedMissingStructureTreeJavaScriptPresentInvalidEmbeddedFile などのカテゴリを持つ 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)?;

コンバータは自動的に以下のアクションを実行します:

  1. XMPメタデータ注入pdfaid:partpdfaid:conformance エントリを追加
  2. フォント埋め込み – 参照されているが埋め込まれていないフォントを埋め込み
  3. JavaScript除去 – JavaScriptアクションとトリガーを除去
  4. 透明度フラット化 – 透明要素を不透明にレンダリング(PDF/A-1のみ)
  5. ICCプロファイル変換 – デバイス依存色をICCベースの色空間に変換
  6. 構造タグ付け – 基本構造タグを追加(レベル「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メタデータ値からレベルをパース

次のステップ