Redact PDF Content
LM-Kit.NET ships a dedicated redaction engine, PdfRedactor, that permanently removes
content from a PDF. Unlike drawing a black rectangle over content, redaction deletes the
underlying data: text glyphs are removed from content streams, image pixels are scrubbed and
re-encoded, vector graphics are trimmed, intersecting annotations are deleted, and content
nested inside Form XObjects is processed per instance. The removed content cannot be recovered
from the output by text extraction, raw stream inspection, or rendering. Surviving content is
untouched: text is removed at glyph granularity, and shared resources are cloned before editing
so only the targeted instance changes. Everything runs 100% on-device and no AI model is required.
What Gets Removed
A single pass can remove several content types under each redacted region:
| Content | Behavior |
|---|---|
| Text | Glyphs under the region are deleted; the rest of the object is rebuilt with its remaining glyphs in place |
| Images | Intersecting pixels are scrubbed and re-encoded; images that cannot be decoded are removed entirely |
| Vector graphics | Paths intersecting the region are removed or trimmed |
| Annotations | Annotations whose rectangle intersects the region are deleted (their markup, link targets, and field values often duplicate the redacted content) |
| Form XObjects | Redaction descends into forms; the affected instance is cloned first so other pages keep the original |
Marking What to Redact
A PdfRedactionRequest describes what to remove. Explicit page areas, text search terms, and
the document's pre-existing /Redact annotations can be combined in one request; everything
matched is removed in a single pass.
using LMKit.Document.Pdf;
using LMKit.Graphics.Geometry;
var request = new PdfRedactionRequest();
// Every occurrence of each term is redacted.
request.SearchTerms.Add("John Doe");
request.SearchTerms.Add("4111 1111 1111 1111");
// A fixed region on page 1, in top-left origin page points.
request.Areas.Add(new PdfRedactionArea(pageIndex: 0, Rectangle.FromSize(left: 72, top: 90, width: 220, height: 30)));
// Also apply any /Redact annotations the file already carries.
request.ApplyExistingRedactAnnotations = true;
An area is any IBounds, so a Rectangle, a layout TextElement, or a PdfSearch match's
bounds can be passed directly. PdfRedactionArea.FromRegion(match) builds areas that hug the
matched glyphs.
Basic Redaction
using LMKit.Document.Pdf;
var request = new PdfRedactionRequest();
request.SearchTerms.Add("John Doe");
var report = PdfRedactor.RedactToFile("contract.pdf", "contract_redacted.pdf", request);
Console.WriteLine($"Matches: {report.SearchMatches}, glyphs removed: {report.RemovedGlyphs}");
Every redaction returns a PdfRedactionReport describing what was removed (removed and edited
text objects, removed glyphs, edited and removed images, removed paths, edited forms, removed
annotations).
Input and Output Modes
The engine accepts file paths, raw bytes, streams, and Attachment objects. Each input mode
ships with RedactToFile, RedactToStream, and RedactToBytes variants, all available
synchronously and asynchronously:
// File to file
var report = await PdfRedactor.RedactToFileAsync("in.pdf", "out.pdf", request);
// Bytes to stream
using var output = File.Create("out.pdf");
var report2 = PdfRedactor.RedactToStream(pdfBytes, output, request);
// Anything to bytes, with the report alongside
PdfRedactionResult result = await PdfRedactor.RedactToBytesAsync("in.pdf", request);
await File.WriteAllBytesAsync("out.pdf", result.Data);
Console.WriteLine(result.Report.ContentRemoved);
Redaction Options
PdfRedactionOptions controls how content is removed and what the redacted area looks like
afterward. The defaults remove every content type intersecting a region and draw an opaque
black box over each redacted area.
using LMKit.Document.Pdf;
using LMKit.Graphics.Primitives;
var options = new PdfRedactionOptions
{
FillColor = Color32.FromRgb(0x333333), // fill box colour; alpha is honored
RemoveAnnotations = false, // keep intersecting annotations
Password = "s3cret", // open an encrypted source
};
var report = PdfRedactor.RedactToFile("in.pdf", "out.pdf", request, options);
| Option | Effect |
|---|---|
DrawFillBoxes |
Draw an opaque box over each redacted area after removal. Default true |
FillColor |
Fill box colour as a Color32; the alpha channel is honored. Default opaque black |
RedactImages |
Scrub image pixels intersecting a region. Default true |
RedactVectorGraphics |
Remove vector paths intersecting a region. Default true |
RemoveAnnotations |
Delete annotations whose rectangle intersects a region. Default true |
RecurseIntoForms |
Descend into Form XObjects (cloning the affected instance). Default true |
Password |
Password used to open an encrypted source. The output is always unencrypted |
Reading the Report
| Property | Meaning |
|---|---|
ContentRemoved |
Whether the pass removed or rewrote any content at all |
PagesProcessed |
Pages that received at least one redaction area |
SearchMatches |
Text search matches that produced redaction areas |
RemovedGlyphs |
Glyphs permanently removed |
RemovedTextObjects / EditedTextObjects |
Text objects removed entirely / rebuilt with fewer glyphs |
EditedImages / RemovedImages |
Images scrubbed in place / removed entirely |
RemovedPaths |
Vector path objects removed or trimmed |
EditedForms |
Form XObject instances cloned and redacted |
RemovedAnnotations |
Annotations removed |