How to Migrate from Nutrient.io to IronPDF in C#
Migrating from Nutrient (formerly PSPDFKit) to IronPDF simplifies your .NET PDF workflow by moving from a broad imaging-and-PDF toolkit to a focused PDF library. Nutrient's server-side .NET offering is GdPicture.NET — the toolkit acquired from ORPALIS and repositioned as the "Nutrient .NET SDK" — which ships as the GdPicture NuGet package under the GdPicture14 namespace. This guide walks through a step-by-step migration path that swaps the procedural, multi-purpose toolkit for a PDF-only library with a smaller surface area.
Why Migrate from Nutrient to IronPDF
The Toolkit Surface-Area Problem
Nutrient (formerly PSPDFKit, rebranded 2024-10-23) sells a multi-product family — Document Engine (Docker microservice), Web SDK, mobile SDKs, and a server-side .NET SDK that is GdPicture under the hood. For teams that need straightforward PDF operations without the rest of the toolkit, the surface area shows up in a few concrete ways:
-
Broad toolkit scope: The .NET SDK covers PDF, OCR, barcodes, TWAIN scanning, image processing, and conversion across more than 100 file formats. Useful if you need that breadth — more surface area than a PDF-only project needs if you don't.
-
Sales-led pricing: The
nutrient.io/sdk/pricingpage routes to a contact form rather than publishing per-developer rates, which makes side-by-side cost comparison harder for small teams. -
Brand and package churn: PSPDFKit → Nutrient (2024-10-23), plus the GdPicture acquisition, means three names to track in older code. The .NET SDK still ships as the
GdPictureNuGet package, namespaceGdPicture14, with class names likeGdPicturePDFandGdPictureDocumentConverterthat do not match the "Nutrient" or "PSPDFKit" branding. -
External browser dependency for HTML-to-PDF: The .NET SDK's HTML renderer relies on a system-installed Chrome or Edge (or a portable path you set via
SetWebBrowserPath). IronPDF ships its own embedded Chromium. - Procedural PDF API: Watermarks compose
SetFillAlpha,DrawTextBox, and OCG layer markers; headers and footers are drawn per page in a loop. Composing common PDF operations from primitives means more code per task.
Nutrient .NET SDK vs IronPDF Comparison
| Aspect | Nutrient .NET SDK (GdPicture) | IronPDF |
|---|---|---|
| Scope | PDF + OCR + barcode + scanning + imaging | PDF library |
| Pricing | Sales-led (contact for quote) | Transparent, published |
| NuGet package | GdPicture |
IronPdf |
| Root namespace | GdPicture14 |
IronPdf |
| API style | Mostly synchronous, procedural draw calls | Sync with async option, fluent |
| HTML rendering | Requires system Chrome / Edge | Embedded Chromium |
| Page indexing | 1-based | 0-based |
| Target users | Teams needing imaging + scanning + PDF in one toolkit | Teams needing PDF only |
For teams on modern .NET who only need PDF, IronPDF provides a smaller, PDF-focused foundation that integrates cleanly without the additional imaging / scanning / OCR layers.
Before You Start
Prerequisites
- .NET Environment: .NET Framework 4.6.2+ or .NET Core 3.1+ / .NET 5/6/7/8/9+
- NuGet Access: Ability to install NuGet packages
- IronPDF License: Obtain your license key from ironpdf.com
NuGet Package Changes
# Remove the Nutrient .NET SDK (GdPicture) and any legacy PSPDFKit-branded packages
dotnet remove package GdPicture
dotnet remove package GdPicture.WPF
dotnet remove package GdPicture.WinForms
dotnet remove package PSPDFKit.NET
# Install IronPDF
dotnet add package IronPdf
# Remove the Nutrient .NET SDK (GdPicture) and any legacy PSPDFKit-branded packages
dotnet remove package GdPicture
dotnet remove package GdPicture.WPF
dotnet remove package GdPicture.WinForms
dotnet remove package PSPDFKit.NET
# Install IronPDF
dotnet add package IronPdf
The current Nutrient .NET SDK ships under the GdPicture NuGet ID (latest 14.x, owner ORPALIS — a Nutrient subsidiary). The older PSPDFKit-branded PSPDFKit.NET package is sunset; remove it if present.
License Configuration
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup (Program.vb or Startup.vb)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Identify Nutrient .NET SDK Usage
# Find GdPicture / Nutrient / PSPDFKit usage
grep -rE "GdPicture14|GdPicturePDF|GdPictureDocumentConverter|PSPDFKit|Nutrient" --include="*.cs" .
# Find GdPicture / Nutrient / PSPDFKit usage
grep -rE "GdPicture14|GdPicturePDF|GdPictureDocumentConverter|PSPDFKit|Nutrient" --include="*.cs" .
Complete API Reference
Initialization Mappings
| Nutrient .NET SDK (GdPicture) | IronPDF |
|---|---|
new GdPicturePDF() |
new PdfDocument(...) / PdfDocument.FromFile(...) |
new GdPictureDocumentConverter() |
new ChromePdfRenderer() |
pdf.Dispose() (IDisposable) |
pdf.Dispose() (IDisposable) |
Document Loading Mappings
| Nutrient .NET SDK (GdPicture) | IronPDF |
|---|---|
pdf.LoadFromFile(path) |
PdfDocument.FromFile(path) |
pdf.LoadFromStream(stream) |
PdfDocument.FromStream(stream) |
pdf.LoadFromByteArray(bytes) |
new PdfDocument(bytes) / PdfDocument.FromBinaryData(bytes) |
PDF Generation Mappings
| Nutrient .NET SDK (GdPicture) | IronPDF |
|---|---|
HTML string: write to temp file, then converter.LoadFromFile(path, DocumentFormat.DocumentFormatHTML) + SaveAsPDF(out) |
renderer.RenderHtmlAsPdf(html) |
converter.LoadFromHttp(url) + SaveAsPDF(out) |
renderer.RenderUrlAsPdf(url) |
converter.LoadFromFile(htmlPath, DocumentFormat.DocumentFormatHTML) + SaveAsPDF(out) |
renderer.RenderHtmlFileAsPdf(path) |
Document Operations Mappings
| Nutrient .NET SDK (GdPicture) | IronPDF |
|---|---|
converter.CombineToPDF(paths, out, PdfConformance.PDF) |
PdfDocument.Merge(pdfs) |
pdf.GetPageCount() |
pdf.PageCount |
pdf.SaveToFile(path) |
pdf.SaveAs(path) |
pdf.SaveToByteArray(out bytes) |
pdf.BinaryData |
Watermarks Mappings
| Nutrient .NET SDK (GdPicture) | IronPDF |
|---|---|
pdf.SetFillAlpha(...) + pdf.DrawTextBox(...) per page |
pdf.ApplyWatermark(html, rotation, vAlign, hAlign) |
pdf.AddStandardFont(...) + draw calls |
HTML/CSS in watermark string |
SetFillAlpha(128) (0–255 byte scale) |
Watermark Opacity 0–100 (int) or CSS opacity |
pdf.SetTextSize(48) |
CSS font-size: 48px |
Code Migration Examples
Example 1: HTML to PDF Conversion
Before (Nutrient .NET SDK / GdPicture):
// NuGet: Install-Package GdPicture
using GdPicture14;
using System.IO;
class Program
{
static void Main()
{
var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
// GdPicture's HTML loader is file-based, so stage the string to disk first.
File.WriteAllText("input.html", htmlContent);
using var converter = new GdPictureDocumentConverter();
converter.LoadFromFile("input.html", DocumentFormat.DocumentFormatHTML);
converter.SaveAsPDF("output.pdf");
}
}
// NuGet: Install-Package GdPicture
using GdPicture14;
using System.IO;
class Program
{
static void Main()
{
var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
// GdPicture's HTML loader is file-based, so stage the string to disk first.
File.WriteAllText("input.html", htmlContent);
using var converter = new GdPictureDocumentConverter();
converter.LoadFromFile("input.html", DocumentFormat.DocumentFormatHTML);
converter.SaveAsPDF("output.pdf");
}
}
Imports GdPicture14
Imports System.IO
Class Program
Shared Sub Main()
Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"
' GdPicture's HTML loader is file-based, so stage the string to disk first.
File.WriteAllText("input.html", htmlContent)
Using converter As New GdPictureDocumentConverter()
converter.LoadFromFile("input.html", DocumentFormat.DocumentFormatHTML)
converter.SaveAsPDF("output.pdf")
End Using
End Sub
End Class
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
End Sub
End Class
The GdPicture approach requires a few extra steps: the HTML loader is file/URL-based, so an in-memory HTML string has to be staged to disk first, then converter.LoadFromFile(...) is called with DocumentFormat.DocumentFormatHTML, followed by SaveAsPDF. HTML rendering relies on a system-installed Chrome or Edge (or a portable path supplied via SetWebBrowserPath).
IronPDF accepts the HTML string directly. Create a ChromePdfRenderer, call RenderHtmlAsPdf(), and save with SaveAs(). No temp file, no host browser dependency — IronPDF ships its own embedded Chromium. See the HTML to PDF documentation for additional rendering options.
Example 2: Merging Multiple PDFs
Before (Nutrient .NET SDK / GdPicture):
// NuGet: Install-Package GdPicture
using GdPicture14;
using System.Collections.Generic;
class Program
{
static void Main()
{
IEnumerable<string> sourceFiles = new List<string>
{
"document1.pdf",
"document2.pdf"
};
using var converter = new GdPictureDocumentConverter();
converter.CombineToPDF(sourceFiles, "merged.pdf", PdfConformance.PDF);
}
}
// NuGet: Install-Package GdPicture
using GdPicture14;
using System.Collections.Generic;
class Program
{
static void Main()
{
IEnumerable<string> sourceFiles = new List<string>
{
"document1.pdf",
"document2.pdf"
};
using var converter = new GdPictureDocumentConverter();
converter.CombineToPDF(sourceFiles, "merged.pdf", PdfConformance.PDF);
}
}
Imports GdPicture14
Imports System.Collections.Generic
Class Program
Shared Sub Main()
Dim sourceFiles As IEnumerable(Of String) = New List(Of String) From {
"document1.pdf",
"document2.pdf"
}
Using converter As New GdPictureDocumentConverter()
converter.CombineToPDF(sourceFiles, "merged.pdf", PdfConformance.PDF)
End Using
End Sub
End Class
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")
End Sub
End Class
The GdPicture merge takes a path-based IEnumerable<string> through converter.CombineToPDF, with a PdfConformance value selecting the output conformance level.
IronPDF works at the document level: load each PDF with PdfDocument.FromFile(), merge with the static PdfDocument.Merge() method, and save. Documents can be passed directly or as an enumerable. Learn more about merging and splitting PDFs.
Example 3: Adding Watermarks
Before (Nutrient .NET SDK / GdPicture):
// NuGet: Install-Package GdPicture
using GdPicture14;
class Program
{
static void Main()
{
using var pdf = new GdPicturePDF();
pdf.LoadFromFile("document.pdf");
pdf.SetMeasurementUnit(PdfMeasurementUnit.PdfMeasurementUnitPoint);
var font = pdf.AddStandardFont(PdfStandardFont.PdfStandardFontHelveticaBold);
int pageCount = pdf.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
pdf.SelectPage(i);
pdf.SetFillAlpha(128); // ~50% (0..255)
pdf.SetTextSize(48);
pdf.SetOriginRotationInDegrees(45);
pdf.DrawTextBox(font, 100, 300, 500, 400, "CONFIDENTIAL",
PdfHorizontalAlignment.PdfHorizontalAlignmentCenter,
PdfVerticalAlignment.PdfVerticalAlignmentMiddle);
}
pdf.SaveToFile("watermarked.pdf");
}
}
// NuGet: Install-Package GdPicture
using GdPicture14;
class Program
{
static void Main()
{
using var pdf = new GdPicturePDF();
pdf.LoadFromFile("document.pdf");
pdf.SetMeasurementUnit(PdfMeasurementUnit.PdfMeasurementUnitPoint);
var font = pdf.AddStandardFont(PdfStandardFont.PdfStandardFontHelveticaBold);
int pageCount = pdf.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
pdf.SelectPage(i);
pdf.SetFillAlpha(128); // ~50% (0..255)
pdf.SetTextSize(48);
pdf.SetOriginRotationInDegrees(45);
pdf.DrawTextBox(font, 100, 300, 500, 400, "CONFIDENTIAL",
PdfHorizontalAlignment.PdfHorizontalAlignmentCenter,
PdfVerticalAlignment.PdfVerticalAlignmentMiddle);
}
pdf.SaveToFile("watermarked.pdf");
}
}
Imports GdPicture14
Class Program
Shared Sub Main()
Using pdf As New GdPicturePDF()
pdf.LoadFromFile("document.pdf")
pdf.SetMeasurementUnit(PdfMeasurementUnit.PdfMeasurementUnitPoint)
Dim font = pdf.AddStandardFont(PdfStandardFont.PdfStandardFontHelveticaBold)
Dim pageCount As Integer = pdf.GetPageCount()
For i As Integer = 1 To pageCount
pdf.SelectPage(i)
pdf.SetFillAlpha(128) ' ~50% (0..255)
pdf.SetTextSize(48)
pdf.SetOriginRotationInDegrees(45)
pdf.DrawTextBox(font, 100, 300, 500, 400, "CONFIDENTIAL", PdfHorizontalAlignment.PdfHorizontalAlignmentCenter, PdfVerticalAlignment.PdfVerticalAlignmentMiddle)
Next
pdf.SaveToFile("watermarked.pdf")
End Using
End Sub
End Class
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
class Program
{
static void Main()
{
var pdf = PdfDocument.FromFile("document.pdf");
pdf.ApplyWatermark("<h1 style='color:gray;opacity:0.5;'>CONFIDENTIAL</h1>",
45,
VerticalAlignment.Middle,
HorizontalAlignment.Center);
pdf.SaveAs("watermarked.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
class Program
{
static void Main()
{
var pdf = PdfDocument.FromFile("document.pdf");
pdf.ApplyWatermark("<h1 style='color:gray;opacity:0.5;'>CONFIDENTIAL</h1>",
45,
VerticalAlignment.Middle,
HorizontalAlignment.Center);
pdf.SaveAs("watermarked.pdf");
}
}
Imports IronPdf
Imports IronPdf.Editing
Class Program
Shared Sub Main()
Dim pdf = PdfDocument.FromFile("document.pdf")
pdf.ApplyWatermark("<h1 style='color:gray;opacity:0.5;'>CONFIDENTIAL</h1>",
45,
VerticalAlignment.Middle,
HorizontalAlignment.Center)
pdf.SaveAs("watermarked.pdf")
End Sub
End Class
This example highlights a fundamental architectural difference. GdPicture uses a procedural draw-call approach: add a standard font, then iterate (1-based) through every page calling SelectPage, SetFillAlpha, SetTextSize, SetOriginRotationInDegrees, and DrawTextBox. Alpha is on a 0–255 byte scale, rotation is set as a graphics-state property, and positioning is handled through explicit coordinates.
IronPDF uses an HTML-based approach: the ApplyWatermark() method accepts an HTML string with CSS styling and applies it to all pages in a single call. You control appearance through familiar CSS properties (color, opacity, font-size) rather than primitive graphics calls. This approach also supports richer content — gradients, images, and more complex layouts — in the same string. See the watermark documentation for advanced examples.
Critical Migration Notes
HTML Input Surface
GdPicture's HTML loader is file/URL-based; IronPDF accepts HTML strings directly:
// Nutrient .NET SDK (string -> file -> PDF):
File.WriteAllText("input.html", html);
converter.LoadFromFile("input.html", DocumentFormat.DocumentFormatHTML);
converter.SaveAsPDF("output.pdf");
// IronPDF (string -> PDF):
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// Nutrient .NET SDK (string -> file -> PDF):
File.WriteAllText("input.html", html);
converter.LoadFromFile("input.html", DocumentFormat.DocumentFormatHTML);
converter.SaveAsPDF("output.pdf");
// IronPDF (string -> PDF):
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
' Nutrient .NET SDK (string -> file -> PDF):
File.WriteAllText("input.html", html)
converter.LoadFromFile("input.html", DocumentFormat.DocumentFormatHTML)
converter.SaveAsPDF("output.pdf")
' IronPDF (string -> PDF):
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
If you do need async operations, IronPDF provides async variants like RenderHtmlAsPdfAsync().
External Browser Dependency
GdPicture's HTML renderer relies on a system Chrome or Edge install (or a portable path you set via SetWebBrowserPath). IronPDF ships its own embedded Chromium:
// Nutrient .NET SDK: optionally point to a portable Chrome
converter.SetWebBrowserPath(@"C:\Tools\chrome\chrome.exe");
// IronPDF: nothing to configure
var pdf = renderer.RenderHtmlAsPdf(html);
// Nutrient .NET SDK: optionally point to a portable Chrome
converter.SetWebBrowserPath(@"C:\Tools\chrome\chrome.exe");
// IronPDF: nothing to configure
var pdf = renderer.RenderHtmlAsPdf(html);
' Nutrient .NET SDK: optionally point to a portable Chrome
converter.SetWebBrowserPath("C:\Tools\chrome\chrome.exe")
' IronPDF: nothing to configure
Dim pdf = renderer.RenderHtmlAsPdf(html)
Configuration Pattern Change
GdPicture exposes layout settings as per-property values on the converter (HTML page width/height in inches, individual margins). IronPDF groups them onto a RenderingOptions bag with named paper sizes:
// Nutrient .NET SDK: properties on the converter (inches)
using var converter = new GdPictureDocumentConverter();
converter.HtmlPageWidth = 8.27f; // A4 width (inches)
converter.HtmlPageHeight = 11.69f; // A4 height (inches)
converter.HtmlMarginTop = 0.78f;
converter.HtmlMarginBottom = 0.78f;
converter.HtmlMarginLeft = 0.78f;
converter.HtmlMarginRight = 0.78f;
// IronPDF: properties on RenderingOptions (millimetres)
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = renderer.RenderHtmlAsPdf(html);
// Nutrient .NET SDK: properties on the converter (inches)
using var converter = new GdPictureDocumentConverter();
converter.HtmlPageWidth = 8.27f; // A4 width (inches)
converter.HtmlPageHeight = 11.69f; // A4 height (inches)
converter.HtmlMarginTop = 0.78f;
converter.HtmlMarginBottom = 0.78f;
converter.HtmlMarginLeft = 0.78f;
converter.HtmlMarginRight = 0.78f;
// IronPDF: properties on RenderingOptions (millimetres)
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = renderer.RenderHtmlAsPdf(html);
Imports GdPicture14
Imports IronPdf
' Nutrient .NET SDK: properties on the converter (inches)
Using converter As New GdPictureDocumentConverter()
converter.HtmlPageWidth = 8.27F ' A4 width (inches)
converter.HtmlPageHeight = 11.69F ' A4 height (inches)
converter.HtmlMarginTop = 0.78F
converter.HtmlMarginBottom = 0.78F
converter.HtmlMarginLeft = 0.78F
converter.HtmlMarginRight = 0.78F
End Using
' IronPDF: properties on RenderingOptions (millimetres)
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
renderer.RenderingOptions.MarginLeft = 20
renderer.RenderingOptions.MarginRight = 20
Dim pdf = renderer.RenderHtmlAsPdf(html)
Procedural Watermarks to HTML Watermarks
Replace primitive draw calls with a single HTML/CSS string:
// Nutrient .NET SDK: SetFillAlpha + SetTextSize + DrawTextBox in a per-page loop
pdf.SetFillAlpha(128);
pdf.SetTextSize(48);
pdf.SetOriginRotationInDegrees(45);
pdf.DrawTextBox(font, 100, 300, 500, 400, "CONFIDENTIAL",
PdfHorizontalAlignment.PdfHorizontalAlignmentCenter,
PdfVerticalAlignment.PdfVerticalAlignmentMiddle);
// IronPDF: one HTML/CSS string
pdf.ApplyWatermark("<h1 style='opacity:0.5; font-size:48px;'>CONFIDENTIAL</h1>",
45, VerticalAlignment.Middle, HorizontalAlignment.Center);
// Nutrient .NET SDK: SetFillAlpha + SetTextSize + DrawTextBox in a per-page loop
pdf.SetFillAlpha(128);
pdf.SetTextSize(48);
pdf.SetOriginRotationInDegrees(45);
pdf.DrawTextBox(font, 100, 300, 500, 400, "CONFIDENTIAL",
PdfHorizontalAlignment.PdfHorizontalAlignmentCenter,
PdfVerticalAlignment.PdfVerticalAlignmentMiddle);
// IronPDF: one HTML/CSS string
pdf.ApplyWatermark("<h1 style='opacity:0.5; font-size:48px;'>CONFIDENTIAL</h1>",
45, VerticalAlignment.Middle, HorizontalAlignment.Center);
' Nutrient .NET SDK: SetFillAlpha + SetTextSize + DrawTextBox in a per-page loop
pdf.SetFillAlpha(128)
pdf.SetTextSize(48)
pdf.SetOriginRotationInDegrees(45)
pdf.DrawTextBox(font, 100, 300, 500, 400, "CONFIDENTIAL", PdfHorizontalAlignment.PdfHorizontalAlignmentCenter, PdfVerticalAlignment.PdfVerticalAlignmentMiddle)
' IronPDF: one HTML/CSS string
pdf.ApplyWatermark("<h1 style='opacity:0.5; font-size:48px;'>CONFIDENTIAL</h1>", 45, VerticalAlignment.Middle, HorizontalAlignment.Center)
Page Number Handling
GdPicture has no first-class header/footer model — page numbers are drawn per page in a loop. IronPDF exposes built-in {page} / {total-pages} placeholders:
// Nutrient .NET SDK: per-page DrawText loop (1-based)
for (int i = 1; i <= pdf.GetPageCount(); i++)
{
pdf.SelectPage(i);
pdf.DrawText(font, x, y, $"Page {i} of {pdf.GetPageCount()}");
}
// IronPDF: built-in placeholders
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "Page {page} of {total-pages}"
};
// Nutrient .NET SDK: per-page DrawText loop (1-based)
for (int i = 1; i <= pdf.GetPageCount(); i++)
{
pdf.SelectPage(i);
pdf.DrawText(font, x, y, $"Page {i} of {pdf.GetPageCount()}");
}
// IronPDF: built-in placeholders
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "Page {page} of {total-pages}"
};
' Nutrient .NET SDK: per-page DrawText loop (1-based)
For i As Integer = 1 To pdf.GetPageCount()
pdf.SelectPage(i)
pdf.DrawText(font, x, y, $"Page {i} of {pdf.GetPageCount()}")
Next
' IronPDF: built-in placeholders
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "Page {page} of {total-pages}"
}
Page Indexing
GdPicture is 1-based (SelectPage(1) is the first page). IronPDF pdf.Pages and pdf.RemovePages(int) are 0-based. Off-by-one is the most common porting bug:
// Nutrient .NET SDK (1-based):
pdf.SelectPage(1);
pdf.DeletePage();
// IronPDF (0-based):
pdf.RemovePages(0);
// Nutrient .NET SDK (1-based):
pdf.SelectPage(1);
pdf.DeletePage();
// IronPDF (0-based):
pdf.RemovePages(0);
Troubleshooting
Issue 1: GdPictureDocumentConverter Not Found
Problem: GdPictureDocumentConverter class doesn't exist in IronPDF.
Solution: Use ChromePdfRenderer for HTML/URL → PDF:
// Nutrient .NET SDK
using var converter = new GdPictureDocumentConverter();
// IronPDF
var renderer = new ChromePdfRenderer();
// Nutrient .NET SDK
using var converter = new GdPictureDocumentConverter();
// IronPDF
var renderer = new ChromePdfRenderer();
Imports GdPicture14
Imports IronPdf
' Nutrient .NET SDK
Using converter As New GdPictureDocumentConverter()
' Your code here
End Using
' IronPDF
Dim renderer As New ChromePdfRenderer()
Issue 2: GdPicturePDF Not Found
Problem: GdPicturePDF class doesn't exist in IronPDF.
Solution: Use PdfDocument:
// Nutrient .NET SDK
using var pdf = new GdPicturePDF();
pdf.LoadFromFile("input.pdf");
// IronPDF
var pdf = PdfDocument.FromFile("input.pdf");
// Nutrient .NET SDK
using var pdf = new GdPicturePDF();
pdf.LoadFromFile("input.pdf");
// IronPDF
var pdf = PdfDocument.FromFile("input.pdf");
Imports GdPicture14
Imports IronPdf
' Nutrient .NET SDK
Using pdf As New GdPicturePDF()
pdf.LoadFromFile("input.pdf")
End Using
' IronPDF
Dim pdfDocument = PdfDocument.FromFile("input.pdf")
Issue 3: DrawTextBox / SetFillAlpha Not Found
Problem: Primitive draw calls don't exist in IronPDF.
Solution: Use HTML-based watermarks:
// Nutrient .NET SDK
pdf.SetFillAlpha(128);
pdf.DrawTextBox(font, 100, 300, 500, 400, "DRAFT",
PdfHorizontalAlignment.PdfHorizontalAlignmentCenter,
PdfVerticalAlignment.PdfVerticalAlignmentMiddle);
// IronPDF
pdf.ApplyWatermark("<div style='opacity:0.5;'>DRAFT</div>",
45, VerticalAlignment.Middle, HorizontalAlignment.Center);
// Nutrient .NET SDK
pdf.SetFillAlpha(128);
pdf.DrawTextBox(font, 100, 300, 500, 400, "DRAFT",
PdfHorizontalAlignment.PdfHorizontalAlignmentCenter,
PdfVerticalAlignment.PdfVerticalAlignmentMiddle);
// IronPDF
pdf.ApplyWatermark("<div style='opacity:0.5;'>DRAFT</div>",
45, VerticalAlignment.Middle, HorizontalAlignment.Center);
' Nutrient .NET SDK
pdf.SetFillAlpha(128)
pdf.DrawTextBox(font, 100, 300, 500, 400, "DRAFT", PdfHorizontalAlignment.PdfHorizontalAlignmentCenter, PdfVerticalAlignment.PdfVerticalAlignmentMiddle)
' IronPDF
pdf.ApplyWatermark("<div style='opacity:0.5;'>DRAFT</div>", 45, VerticalAlignment.Middle, HorizontalAlignment.Center)
Issue 4: CombineToPDF Not Found
Problem: Path-based combine method doesn't exist.
Solution: Load each PDF as a PdfDocument and use static PdfDocument.Merge():
// Nutrient .NET SDK
converter.CombineToPDF(paths, "merged.pdf", PdfConformance.PDF);
// IronPDF
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
// Nutrient .NET SDK
converter.CombineToPDF(paths, "merged.pdf", PdfConformance.PDF);
// IronPDF
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
' Nutrient .NET SDK
converter.CombineToPDF(paths, "merged.pdf", PdfConformance.PDF)
' IronPDF
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")
Issue 5: Off-by-One Page Index
Problem: GdPicture uses 1-based page indices; IronPDF uses 0-based. Direct ports of SelectPage(1) to pdf.Pages[1] skip the first page.
Solution: Subtract one when porting page indices:
// Nutrient .NET SDK (first page)
pdf.SelectPage(1);
// IronPDF (first page)
var firstPage = pdf.Pages[0];
// Nutrient .NET SDK (first page)
pdf.SelectPage(1);
// IronPDF (first page)
var firstPage = pdf.Pages[0];
' Nutrient .NET SDK (first page)
pdf.SelectPage(1)
' IronPDF (first page)
Dim firstPage = pdf.Pages(0)
Migration Checklist
Pre-Migration
- Inventory all GdPicture / PSPDFKit / Nutrient usages in the codebase
- Note 1-based vs 0-based page indexing in existing GdPicture code
- List configuration set on
GdPictureDocumentConverter(HTML page dimensions, margins) - Identify procedural drawing for watermarks and headers (
SetFillAlpha,DrawTextBox) - Review form-field code that uses index-based access (
GetFormFieldName(i)) - Obtain IronPDF license key
Package Changes
- Remove
GdPictureNuGet package (andGdPicture.WPF/GdPicture.WinFormsif present) - Remove the legacy
PSPDFKit.NETpackage if present - Install
IronPdfNuGet package:dotnet add package IronPdf - Update namespace imports (
using GdPicture14;→using IronPdf;)
Code Changes
- Add license key configuration at startup
- Replace
new GdPictureDocumentConverter()withnew ChromePdfRenderer()for HTML/URL → PDF - Replace
new GdPicturePDF()+LoadFromFilewithPdfDocument.FromFile() - Replace
converter.CombineToPDF(paths, ...)withPdfDocument.Merge() - Convert procedural watermark draw calls to
pdf.ApplyWatermark(html, ...) - Replace converter properties with
RenderingOptions(named paper sizes, mm margins) - Update headers/footers to
HtmlHeaderFooterwith{page}/{total-pages}tokens - Convert 1-based page indices to 0-based throughout
Post-Migration
- Remove the system Chrome / Edge dependency from deployment images if it was only there for GdPicture
- Run regression tests comparing PDF output
- Verify headers/footers with page numbers
- Test watermark rendering
- Update CI/CD pipeline

