Nedo.AspNet.PdfEngine
1.0.0
See the version list below for details.
dotnet add package Nedo.AspNet.PdfEngine --version 1.0.0
NuGet\Install-Package Nedo.AspNet.PdfEngine -Version 1.0.0
<PackageReference Include="Nedo.AspNet.PdfEngine" Version="1.0.0" />
<PackageVersion Include="Nedo.AspNet.PdfEngine" Version="1.0.0" />
<PackageReference Include="Nedo.AspNet.PdfEngine" />
paket add Nedo.AspNet.PdfEngine --version 1.0.0
#r "nuget: Nedo.AspNet.PdfEngine, 1.0.0"
#:package Nedo.AspNet.PdfEngine@1.0.0
#addin nuget:?package=Nedo.AspNet.PdfEngine&version=1.0.0
#tool nuget:?package=Nedo.AspNet.PdfEngine&version=1.0.0
Nedo.AspNet.PdfEngine
ASP.NET Core library for PDF manipulation — watermarking, image rasterization (anti-copy), compression, and encryption at rest.
Installation
dotnet add package Nedo.AspNet.PdfEngine
Quick Start
1. Register Services
builder.Services
.AddPdfEngine() // Core service
.AddWatermark() // Text / Stamp / Image watermark
.AddRasterization() // PDF → image-based pages (anti-copy)
.AddCompression() // FlateEncode compression
.AddEncryption(); // AES password protection
2. Use the Service
app.MapPost("/pdf/watermark", async (IFormFile file, IPdfService pdfService) =>
{
using var ms = new MemoryStream();
await file.CopyToAsync(ms);
var request = new PdfOperationBuilder()
.WithInput(ms.ToArray())
.AddWatermark(opt =>
{
opt.Text = "CONFIDENTIAL";
opt.Opacity = 0.3;
opt.Repeat = true;
})
.Build();
var result = await pdfService.ProcessAsync(request);
return Results.File(result.OutputPdf!, "application/pdf", "watermarked.pdf");
});
Features
1. Text Watermark
Transparent text overlaid across the page — tiled or single-positioned.
// Tiled diagonal text
.AddWatermark(opt =>
{
opt.Text = "DRAFT";
opt.FontSize = 72;
opt.Opacity = 0.15;
opt.Rotation = -45;
opt.Color = "#FF5252";
opt.Repeat = true;
opt.RepeatSpacing = 150;
})
// Single positioned text (bottom-right)
.AddWatermark(opt =>
{
opt.Text = "Confidential";
opt.FontSize = 36;
opt.Opacity = 0.3;
opt.Repeat = false;
opt.Position = WatermarkPosition.BottomRight;
opt.Margin = 20;
})
// Fit diagonal — auto-sizes to span full page diagonal
.AddWatermark(opt =>
{
opt.Text = "DRAFT";
opt.FitDiagonal = true; // auto FontSize & Rotation
opt.Repeat = false;
opt.Opacity = 0.15;
opt.Color = "#FF5252";
opt.Margin = 80; // padding from corners
})
2. Stamp Watermark (Info-Box)
A box with background, border, and multi-line text — placed at any of 9 positions.
┌───────────┬────────────┬────────────┐
│ TopLeft │ TopCenter │ TopRight │
├───────────┼────────────┼────────────┤
│CenterLeft │ Center │CenterRight │
├───────────┼────────────┼────────────┤
│BottomLeft │BottomCenter│BottomRight │
└───────────┴────────────┴────────────┘
.AddStamp(opt =>
{
opt.Text = "DOKUMEN TIDAK TERKENDALI\n"
+ "Diunduh dari IP Address 103.175.159.20\n"
+ "Tanggal 22-02-2026 18:21:03\n"
+ "Oleh John Doe (johndoe@gmail.com)\n"
+ "Bersifat Private";
opt.Position = WatermarkPosition.TopCenter;
opt.Color = "#E8356D";
opt.BackgroundColor = "#FFF0F0";
opt.BorderColor = "#E8356D";
opt.FontSize = 11;
opt.Padding = 12;
opt.Margin = 20;
opt.BoldFirstLine = true;
opt.Opacity = 0.75;
})
// Simple shorthand
.AddStamp("CONFIDENTIAL\nInternal Only", WatermarkPosition.TopRight)
3. Image Watermark
Overlay a PNG/JPEG image with transparency support.
.AddImageWatermark(opt =>
{
opt.ImageBytes = File.ReadAllBytes("logo.png");
opt.Position = WatermarkPosition.BottomRight;
opt.ImageScale = 0.5; // half size
opt.Opacity = 0.3;
opt.Margin = 30;
})
// Simple shorthand
.AddImageWatermark(logoBytes, WatermarkPosition.Center)
4. Rasterization (Anti-Copy)
Converts each page to a flat image — text becomes non-selectable and non-copiable.
.Rasterize(opt =>
{
opt.Dpi = 200; // 150 = screen, 300 = print
opt.ImageFormat = RasterImageFormat.Png; // or Jpeg
opt.Quality = 85; // JPEG quality (1–100)
})
5. Compression
Reduces PDF file size via FlateEncode and optional image re-encoding.
.Compress(opt =>
{
opt.Level = PdfCompressionLevel.Maximum;
opt.CompressImages = true;
opt.ImageQuality = 75;
})
6. Encryption
Password-protect with granular permissions.
.Encrypt(opt =>
{
opt.OwnerPassword = "admin123"; // full access
opt.UserPassword = "viewer456"; // required to open
opt.AllowPrint = true;
opt.AllowCopy = false;
opt.AllowModify = false;
opt.AllowAnnotations = false;
})
// Simple shorthand
.Encrypt("admin-password", "viewer-password")
7. Pipeline (Chaining Operations)
Apply multiple operations in sequence:
var (input, operations) = new PdfPipelineBuilder()
.WithInput(pdfBytes)
.AddWatermark(opt => { opt.Text = "CONFIDENTIAL"; opt.Repeat = true; })
.AddRasterize(opt => opt.Dpi = 200)
.AddCompress()
.AddEncrypt(opt => opt.OwnerPassword = "secret")
.Build();
var result = await pdfService.ProcessPipelineAsync(input, operations);
Property Reference
WatermarkOptions
Shared Properties (All Styles)
| Property | Type | Default | Description |
|---|---|---|---|
Text |
string |
required | Watermark text. Supports \n for multi-line. |
Style |
WatermarkStyle |
Text |
Rendering style: Text, Stamp, or Image. |
Position |
WatermarkPosition |
Center |
Placement on page. See 9-position grid above. |
FontSize |
double? |
48 (text) / 11 (stamp) |
Font size in PDF points. Auto if null. |
FontFamily |
string |
"Arial" |
Font family name. |
Opacity |
double? |
0.3 (text) / 0.85 (stamp) / 0.5 (image) |
0.0 = invisible, 1.0 = fully opaque. |
Rotation |
double? |
-45 (text) / 0 (stamp/image) |
Rotation angle in degrees. |
Color |
string? |
"#808080" (text) / "#E8356D" (stamp) |
Hex color string, e.g. "#FF5252". |
Margin |
double |
20 |
Distance from page edge in PDF points (72pt = 1 inch). |
Text-Specific Properties
| Property | Type | Default | Description |
|---|---|---|---|
Repeat |
bool? |
true (text) / false (stamp/image) |
Tile watermark across the page in a grid. |
RepeatSpacing |
double |
150 |
Gap between tiles in points. Only when Repeat = true. |
FitDiagonal |
bool |
false |
Auto-size text to span full page diagonal (bottom-left → top-right). Overrides FontSize and Rotation. Only when Repeat = false. |
Stamp-Specific Properties
| Property | Type | Default | Description |
|---|---|---|---|
BackgroundColor |
string |
"#FFF0F0" |
Box background color as hex. |
BorderColor |
string? |
Same as Color |
Box border color as hex. |
BorderWidth |
double |
1.5 |
Border thickness in points. |
Padding |
double |
12 |
Inner padding inside the stamp box in points. |
LineSpacing |
double |
1.4 |
Line height multiplier for multi-line text. |
BoldFirstLine |
bool |
true |
Make the first line bold (e.g. title). |
Image-Specific Properties
| Property | Type | Default | Description |
|---|---|---|---|
ImageBytes |
byte[]? |
null |
Raw image bytes (PNG or JPEG). Required for Style = Image. |
ImageWidth |
double? |
Native width | Override width in points. |
ImageHeight |
double? |
Native height | Override height in points. |
ImageScale |
double? |
1.0 |
Scale factor. 0.5 = half, 2.0 = double. |
RasterizeOptions
| Property | Type | Default | Description |
|---|---|---|---|
Dpi |
int |
150 |
Rendering resolution. 150 = screen quality, 300 = print quality. Higher = sharper but larger file. |
ImageFormat |
RasterImageFormat |
Jpeg |
Output format: Jpeg (smaller) or Png (lossless). |
Quality |
int |
85 |
JPEG compression quality (1–100). Only used when ImageFormat = Jpeg. |
CompressionOptions
| Property | Type | Default | Description |
|---|---|---|---|
Level |
PdfCompressionLevel |
Default |
Compression level: None, Default, or Maximum. |
CompressImages |
bool |
false |
Re-encode embedded images at lower quality. Effective for image-heavy PDFs. |
ImageQuality |
int |
75 |
JPEG quality for re-encoded images (1–100). Only used when CompressImages = true. |
EncryptionOptions
| Property | Type | Default | Description |
|---|---|---|---|
OwnerPassword |
string |
required | Full-access password. Grants modify, print, copy rights. |
UserPassword |
string? |
null |
Password to open the document. If null, opens without password but is still encrypted. |
AllowPrint |
bool |
false |
Allow printing. |
AllowCopy |
bool |
false |
Allow copying text and images. |
AllowModify |
bool |
false |
Allow document modifications. |
AllowAnnotations |
bool |
false |
Allow adding/editing annotations and form fields. |
Enums
WatermarkStyle
| Value | Description |
|---|---|
Text |
Classic transparent text, optionally rotated and tiled. |
Stamp |
Info-box with background, border, and multi-line text. |
Image |
PNG/JPEG overlay with transparency support. |
WatermarkPosition
| Value | Description |
|---|---|
TopLeft |
Top-left corner |
TopCenter |
Top-center |
TopRight |
Top-right corner |
CenterLeft |
Center-left |
Center |
Dead center of the page |
CenterRight |
Center-right |
BottomLeft |
Bottom-left corner |
BottomCenter |
Bottom-center |
BottomRight |
Bottom-right corner |
PdfCompressionLevel
| Value | Description |
|---|---|
None |
No compression. Useful for debugging. |
Default |
FlateEncode. Good balance of speed and size. |
Maximum |
Maximum compression. Slower but smaller. |
RasterImageFormat
| Value | Description |
|---|---|
Jpeg |
Lossy compression, smaller file size. |
Png |
Lossless compression, larger file size. |
PdfResult
| Property | Type | Description |
|---|---|---|
IsSuccess |
bool |
Whether the operation completed successfully. |
OutputPdf |
byte[]? |
Processed PDF bytes. null on failure. |
ErrorMessage |
string? |
Error details. null on success. |
OperationType |
PdfOperationType |
The operation that was performed. |
OutputSizeBytes |
long? |
Size of the output PDF in bytes. |
InputSizeBytes |
long? |
Size of the input PDF in bytes. |
CompletedAt |
DateTimeOffset? |
UTC timestamp when the operation completed. |
Health Check
builder.Services.AddPdfEngineHealthCheck();
app.MapHealthChecks("/health");
Extending
Implement IPdfProcessor and register it:
public class MyCustomProcessor : IPdfProcessor
{
public PdfOperationType OperationType => PdfOperationType.Watermark;
public Task<PdfResult> ProcessAsync(PdfRequest request, CancellationToken ct)
{
// Custom logic
}
}
services.AddSingleton<IPdfProcessor, MyCustomProcessor>();
Docker / Linux
The library uses PDFsharp 6 and Docnet.Core (PDFium). For Linux/Docker containers:
RUN apt-get update && apt-get install -y \
fonts-dejavu-core \
fontconfig \
libgdiplus
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Docnet.Core (>= 2.6.0)
- PDFsharp (>= 6.2.4)
- SkiaSharp (>= 3.116.1)
- SkiaSharp.NativeAssets.Linux.NoDependencies (>= 3.116.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.