👉 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:
- 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.
- 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:
PdfAConversionReportlists 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; setPdfAConversionOptions.Password.- Output used the raster fallback unexpectedly: check
report.RasterTriggersfor the violations that forced it, and considerFallbackBehavior.ReportOnlyto 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
DocumentToMarkdownto index the archived documents for RAG. - Use
FallbackBehavior.Failin validation pipelines where rasterization is not acceptable. - Batch-convert with
ConvertToBytesAsyncand stream results directly to object storage.