Table of Contents

👉 Try the demo: https://github.com/LM-Kit/lm-kit-net-samples/tree/main/console_net/document-intelligence/pdf-toolkit/pdf_to_pdfa_converter

PDF to PDF/A Conversion for C# .NET Applications


🎯 Purpose of the Demo

This demo shows how to convert existing PDF documents to the PDF/A archival format (ISO 19005) with the PdfAConverter class: a single static call that repairs the document, embeds missing fonts, calibrates colours, removes prohibited constructs, rebuilds archival metadata, and reports exactly what was changed. The conversion runs fully on-device, requires no AI model, and guarantees a conforming output even for documents the rewrite cannot repair, thanks to a raster fallback with an invisible searchable text layer.

👥 Who Should Use This Demo (Target Audience)

  • Enterprise developers building document archiving, records management, or legal-hold pipelines.
  • Compliance teams required to store invoices, contracts, or government records as PDF/A.
  • ECM and DMS integrators who need reliable, self-hosted PDF/A conversion without cloud services.
  • Anyone who needs PDFs to remain readable and reproducible decades from now.

🚀 What Problem It Solves

Ordinary PDFs depend on their environment: fonts installed on the viewing machine, device-dependent colours, external references, scripts, and encryption. Years later, such files may render differently or not open at all. PDF/A removes every external dependency, which is why archives, courts, and regulators mandate it. Producing PDF/A from arbitrary real-world PDFs is hard: fonts must be embedded with consistent metrics, colour spaces calibrated, compression re-encoded, and metadata rebuilt, all without changing how the document looks. This demo turns that whole problem into one API call with a detailed report.

💻 Demo Application Overview

The console application offers two interactive modes:

  1. File mode: convert a single PDF, choosing the conformance level (PDF/A-1b, 2b, or 3b), the fallback behavior, and an optional password for encrypted sources.
  2. Folder mode: batch-convert every PDF in a folder with a per-file outcome summary.

Each conversion prints the report: conformance verdict, page count, strategy used (conforming rewrite or raster fallback), detected features, applied fixes, and any unresolved violations.

✨ Key Features

  • One-call conversion: PdfAConverter.ConvertToFileAsync(input, output, options).
  • Three conformance levels: PDF/A-1b, PDF/A-2b (default), and PDF/A-3b.
  • Content-preserving rewrite: text, vector graphics, and layout survive conversion; the raster fallback only engages when repair is impossible.
  • Font repair: non-embedded fonts are replaced by embedded equivalents with reconciled widths; embedded programs are fixed to satisfy conformance rules.
  • Colour calibration: DeviceCMYK and friends are calibrated through embedded ICC profiles; an sRGB output intent is installed.
  • Encrypted input support: pass PdfAConversionOptions.Password; the output is always unencrypted as the standard requires.
  • Actionable report: PdfAConversionReport lists detected features, applied fixes, raster triggers, and the conformance verdict.
  • No model, no cloud: pure document processing, fully local.

Example Output

  invoice.pdf -> invoice_pdfa.pdf
  Level            : PdfA2b
  Conforms         : True
  Pages            : 3
  Strategy         : conforming rewrite (content preserved)
  Features detected: UnembeddedFont, DeviceCmyk
  Fixes applied    : MiscKeys, FontsEmbedded, DefaultCmykInstalled
  Elapsed          : 412 ms

🏗️ Architecture

┌────────────────────┐
│   Source PDF       │  path / bytes / stream / Attachment
└─────────┬──────────┘
          │
┌─────────▼──────────┐
│ Analyze + Sanitize │  prohibited constructs removed, features detected
└─────────┬──────────┘
          │
┌─────────▼──────────┐
│   Repair passes    │  font embedding + metrics, colour calibration,
│                    │  compression re-encoding, content normalization
└─────────┬──────────┘
          │
    ┌─────┴──────┐
    │ repairable?│
    └─────┬──────┘
     yes  │   no
┌─────────▼───────┐  ┌────────────────────────┐
│ Conforming      │  │ Raster fallback        │
│ rewrite         │  │ (pages rendered +      │
│ (content kept)  │  │ invisible text layer)  │
└─────────┬───────┘  └───────────┬────────────┘
          │                      │
┌─────────▼──────────────────────▼─────┐
│ PDF/A output + PdfAConversionReport  │
└──────────────────────────────────────┘

⚙️ Getting Started

Prerequisites

  • .NET 8.0 or later
  • No model download and no GPU required

Download and Run

git clone https://github.com/LM-Kit/lm-kit-net-samples.git
cd lm-kit-net-samples/console_net/document-intelligence/pdf-toolkit/pdf_to_pdfa_converter
dotnet run

Minimal Integration

using LMKit.Document.Pdf;

var report = PdfAConverter.ConvertToFile("input.pdf", "output_pdfa.pdf");

if (report.Conforms)
{
    Console.WriteLine($"Archived as {report.Level}, fixes: {report.FixesApplied}");
}

🔧 Troubleshooting

  • PdfDocumentException: Password required or incorrect password: the source is encrypted; set PdfAConversionOptions.Password.
  • Output used the raster fallback unexpectedly: check report.RasterTriggers for the violations that forced it, and consider FallbackBehavior.ReportOnly to inspect what a rewrite would leave unresolved.
  • File size grew: font embedding and image re-encoding add data by design; PDF/A requires self-containment.

🚀 Extend the Demo

  • Wire the converter into a folder watcher for automatic archive ingestion.
  • Combine with DocumentToMarkdown to index the archived documents for RAG.
  • Use FallbackBehavior.Fail in validation pipelines where rasterization is not acceptable.
  • Batch-convert with ConvertToBytesAsync and stream results directly to object storage.

📚 Additional Resources

Share