Table of Contents

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

See Also

Share