Convert PDF to PDF/A
LM-Kit.NET ships a dedicated archival converter, PdfAConverter, that turns any existing PDF
into a self-contained PDF/A document (ISO 19005). Fonts are embedded with reconciled metrics,
device colours are calibrated through embedded ICC profiles, prohibited constructs
(JavaScript, launch actions, encryption, external references) are removed, prohibited
compression is re-encoded, and XMP archival metadata is rebuilt. Text, vector graphics, and
layout are preserved. Everything runs 100% on-device and no AI model is required.
Conformance Levels
| Level | Standard | Notes |
|---|---|---|
PdfA1b |
ISO 19005-1, level B | Based on PDF 1.4; prohibits transparency and JPEG2000 |
PdfA2b |
ISO 19005-2, level B | Based on PDF 1.7; the level most archives request. Default |
PdfA3b |
ISO 19005-3, level B | PDF/A-2b plus embedded files of any format |
Basic Conversion
using LMKit.Document.Pdf;
var report = PdfAConverter.ConvertToFile("invoice.pdf", "invoice_pdfa.pdf");
Console.WriteLine($"Conforms: {report.Conforms}");
Console.WriteLine($"Fixes applied: {report.FixesApplied}");
Every conversion returns a PdfAConversionReport describing what was detected
(FeaturesDetected), what was repaired (FixesApplied), how the output was produced
(UsedRasterFallback, RasterTriggers), and whether the result conforms.
Input and Output Modes
The converter accepts file paths, raw bytes, streams, and Attachment objects. Each input
mode ships with ConvertToFile, ConvertToStream, and ConvertToBytes variants, all
available synchronously and asynchronously:
// File to file
var report = await PdfAConverter.ConvertToFileAsync("in.pdf", "out.pdf");
// Bytes to stream
using var output = File.Create("out.pdf");
var report2 = PdfAConverter.ConvertToStream(pdfBytes, output);
// Anything to bytes, with the report alongside
PdfAConversionResult result = await PdfAConverter.ConvertToBytesAsync("in.pdf");
await File.WriteAllBytesAsync("out.pdf", result.Data);
Console.WriteLine(result.Report.FixesApplied);
Choosing the Fallback Behavior
Some documents carry violations the conforming rewrite cannot repair. The
PdfAConversionOptions.Fallback setting decides what happens:
| Behavior | Effect |
|---|---|
Rasterize (default) |
Rebuild the document from rendered page images with an invisible, searchable text layer. Guarantees a conforming output. |
Fail |
Throw a PdfDocumentException instead of producing a non-conforming file. |
ReportOnly |
Produce the best-effort rewrite and list what remains in Report.UnresolvedViolations. |
using LMKit.Document.Pdf;
var options = new PdfAConversionOptions
{
Level = PdfAConformanceLevel.PdfA3b,
Fallback = PdfAConversionOptions.FallbackBehavior.Fail,
};
var report = await PdfAConverter.ConvertToFileAsync("contract.pdf", "contract_pdfa.pdf", options);
When the raster fallback engages, RasterDpi (default 200) and RasterJpegQuality
(default 92) control the page image quality, and IncludeInvisibleTextLayer (default
true) keeps the output searchable by overlaying the source text invisibly.
Encrypted Sources
PDF/A prohibits encryption, so the converter always produces an unencrypted output. To open an encrypted source, supply the password:
var options = new PdfAConversionOptions { Password = "secret" };
var report = PdfAConverter.ConvertToFile("locked.pdf", "archived.pdf", options);
Console.WriteLine(report.EncryptionRemoved); // True
Batch Archiving Pattern
using LMKit.Document.Pdf;
foreach (string file in Directory.EnumerateFiles(inbox, "*.pdf"))
{
string target = Path.Combine(archive, Path.GetFileNameWithoutExtension(file) + "_pdfa.pdf");
try
{
var report = await PdfAConverter.ConvertToFileAsync(file, target, cancellationToken: ct);
log.Info($"{file}: {report.Level}, fixes={report.FixesApplied}, raster={report.UsedRasterFallback}");
}
catch (LMKit.Exceptions.PdfDocumentException e)
{
log.Warn($"{file}: {e.Message}"); // damaged or password-protected source
}
}
Reading the Report
| Property | Meaning |
|---|---|
Conforms |
Whether the output is believed to conform to the targeted level |
Level |
The conformance level that was targeted |
PageCount |
Pages in the produced document |
FeaturesDetected |
Conformance-relevant features found in the source (unembedded fonts, DeviceCMYK, LZW, JPEG2000, transparency, scripts, ...) |
FixesApplied |
Repairs performed by the conversion (fonts embedded, colours calibrated, compression re-encoded, ...) |
UsedRasterFallback |
Whether the output was rebuilt from rendered pages |
RasterTriggers |
The violations that forced the raster fallback, when it was used |
EncryptionRemoved |
Whether the source was encrypted |
UnresolvedViolations |
Violations remaining in the output (only under ReportOnly) |