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