Skip to footer content
MIGRATION GUIDES

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:

  1. 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.

  2. Sales-led pricing: The nutrient.io/sdk/pricing page routes to a contact form rather than publishing per-developer rates, which makes side-by-side cost comparison harder for small teams.

  3. 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 GdPicture NuGet package, namespace GdPicture14, with class names like GdPicturePDF and GdPictureDocumentConverter that do not match the "Nutrient" or "PSPDFKit" branding.

  4. 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.

  5. 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

  1. .NET Environment: .NET Framework 4.6.2+ or .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGet Access: Ability to install NuGet packages
  3. 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
SHELL

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"
$vbLabelText   $csharpLabel

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" .
SHELL

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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")
$vbLabelText   $csharpLabel

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)
$vbLabelText   $csharpLabel

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)
$vbLabelText   $csharpLabel

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)
$vbLabelText   $csharpLabel

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}"
}
$vbLabelText   $csharpLabel

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);
$vbLabelText   $csharpLabel

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()
$vbLabelText   $csharpLabel

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")
$vbLabelText   $csharpLabel

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)
$vbLabelText   $csharpLabel

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")
$vbLabelText   $csharpLabel

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)
$vbLabelText   $csharpLabel

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 GdPicture NuGet package (and GdPicture.WPF / GdPicture.WinForms if present)
  • Remove the legacy PSPDFKit.NET package if present
  • Install IronPdf NuGet package: dotnet add package IronPdf
  • Update namespace imports (using GdPicture14;using IronPdf;)

Code Changes

  • Add license key configuration at startup
  • Replace new GdPictureDocumentConverter() with new ChromePdfRenderer() for HTML/URL → PDF
  • Replace new GdPicturePDF() + LoadFromFile with PdfDocument.FromFile()
  • Replace converter.CombineToPDF(paths, ...) with PdfDocument.Merge()
  • Convert procedural watermark draw calls to pdf.ApplyWatermark(html, ...)
  • Replace converter properties with RenderingOptions (named paper sizes, mm margins)
  • Update headers/footers to HtmlHeaderFooter with {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

Please noteNutrient, PSPDFKit, GdPicture, and ORPALIS are trademarks of their respective owners. This site is not affiliated with, endorsed by, or sponsored by Nutrient, PSPDFKit, GdPicture, or ORPALIS. All product names, logos, and brands are property of their respective owners. Comparisons are for informational purposes only and reflect publicly available information at the time of writing.

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me