Text extraction
var textItems = await pdf.ExtractTextAsync();
foreach (var item in textItems)
{
Console.WriteLine(item.Text);
}
Developer Documentation
Reference material and integration guidance for the core API surface.
Quick Start
The main entry points are Pdf.Load(...) for existing documents and
Pdf.Create(...) for new ones.
using var input = File.OpenRead("input.pdf");
using var pdf = Pdf.Load(input);
var pageCount = await pdf.GetPageCountAsync();
var firstPage = await pdf.GetPageAsync(1);
using var pdf = Pdf.Create(options =>
{
options.MediaBox = Rectangle.FromDimensions(595, 842);
});
using var output = File.Create("blank.pdf");
await pdf.SaveAsync(output);
using var pdf = Pdf.Load(File.OpenRead("input.pdf"));
await pdf.AppendPageAsync(options =>
{
options.MediaBox = Rectangle.FromDimensions(595, 842);
});
await pdf.InsertPageAsync(1, options =>
{
options.MediaBox = Rectangle.FromDimensions(300, 300);
});
await pdf.DeletePageAsync(2);
await pdf.SaveAsync(File.Create("pages-updated.pdf"));
var textItems = await pdf.ExtractTextAsync();
foreach (var item in textItems)
{
Console.WriteLine(item.Text);
}
await pdf.AddWatermarkAsync("DRAFT");
pdf.Compress(dpi: 72, quality: 75);
await pdf.SaveAsync(output);
Packages
The ZingPDF solution is split into a small set of packages and support projects with different runtime expectations. If you are choosing what to ship, start here.
ZingPDFThe main PDF library for loading, creating, editing, merging, watermarking, compression, forms, metadata, and encryption.
net8.0SkiaSharp and ImageSharp, so runtime
validation across operating systems mattersZingPDF.FromHTMLOptional HTML-to-PDF support layered on top of the main package.
net8.0ZingPDF unless you specifically need HTML
conversion.ZingPDF.FromHTML as a separate deployment concern with its own operational
requirements.net8.0-first until the dependency surface is slimmed
enough to justify broader multi-targeting.The symbol-by-symbol reference now lives on a dedicated static page generated from the XML docs and source signatures.
Metadata
Use GetMetadataAsync() to read or update the trailer Info dictionary through a
higher-level wrapper.
Title, Author, Subject, Keywords,
Creator, and CreationDate.
Producer is stamped to ZingPDF and
ModifiedDate is refreshed on save.
var metadata = await pdf.GetMetadataAsync();
metadata.Title = "Quarterly Report";
metadata.Author = "Taylor Smith";
metadata.Subject = "Q1 FY2026";
metadata.Keywords = "finance,quarterly";
metadata.Creator = "Back Office Importer";
metadata.CreationDate = new DateTimeOffset(2026, 3, 1, 9, 0, 0, TimeSpan.Zero);
await pdf.SaveAsync(output);
Forms
If a document contains an AcroForm, GetFormAsync() returns a Form wrapper that
can enumerate terminal fields and expose typed behavior for supported field families.
Form.GetFieldsAsync() returns terminal fields as IFormField instances.Applicant.Address.Suburb.var form = await pdf.GetFormAsync();
if (form is null)
{
return;
}
foreach (var field in await form.GetFieldsAsync())
{
switch (field)
{
case TextFormField textField when textField.Name == "Applicant.Name":
await textField.SetValueAsync("Taylor Smith");
break;
case ChoiceFormField choiceField when choiceField.Name == "Applicant.State":
var options = await choiceField.GetOptionsAsync();
var selected = options.FirstOrDefault(x => x.Text.DecodeText() == "NSW");
if (selected is not null)
{
await selected.SelectAsync();
}
break;
}
}
TextFormField currently has the richest editing support.
GetValueAsync()SetValueAsync(string?)ClearAsync()Choice items and selectable button options can be read and toggled through option wrappers like
ChoiceItem and SelectableOption.
Encryption
ZingPDF supports authenticating encrypted PDFs, applying password protection to plain PDFs, and saving decrypted output from encrypted input.
using var pdf = Pdf.Load(File.OpenRead("encrypted.pdf"));
await pdf.AuthenticateAsync("password");
var pageCount = await pdf.GetPageCountAsync();
using var pdf = Pdf.Create();
await pdf.EncryptAsync("user-password", "owner-password");
await pdf.SaveAsync(File.Create("protected.pdf"));
using var pdf = Pdf.Load(File.OpenRead("encrypted.pdf"));
await pdf.DecryptAsync("password");
await pdf.SaveAsync(File.Create("decrypted.pdf"));
Save Behavior
ZingPDF saves by writing an incremental update. That gives you a predictable editing model, but it comes with a few practical constraints you should understand before shipping at scale.
Pdf.Load(...) must be seekable.SaveAsync(...) must be writable and seekable.Form updates and metadata stamping are both applied as part of the save pipeline.
using var pdf = Pdf.Load(File.OpenRead("input.pdf"));
await pdf.AddWatermarkAsync("INTERNAL");
await pdf.SaveAsync(File.Create("output.pdf"));
Implementation Notes
V=2 and
R=3.
DecryptAsync(...) removes encryption in the latest saved revision, but older encrypted
revisions may still exist in the file bytes because saves are incremental.Compress(...) currently compresses unfiltered streams and can recompress JPEG image
streams.DecompressAsync() skips JPEG image streams to avoid forced decompression corruption.InsertPageAsync(...) inserts before the requested page number, while
AppendPageAsync(...) adds to the end.
Low-Level Access
If you need lower-level control, IPdf.Objects exposes the underlying PDF object collection
and page tree. Most application code should prefer the higher-level Pdf and Page
APIs first, but the lower-level surface is there for advanced integrations.