How to Migrate from GdPicture.NET SDK to IronPDF in C#
Migrating from GdPicture.NET SDK to IronPDF offers .NET developers a focused, streamlined approach to PDF generation. This guide provides a comprehensive, step-by-step migration path that replaces complex document imaging SDK patterns with modern, PDF-specific APIs designed for contemporary .NET development.
Why Migrate from GdPicture.NET SDK to IronPDF
The GdPicture.NET SDK Challenges
GdPicture.NET SDK (now rebranded as Nutrient) is a comprehensive document imaging SDK with several challenges for PDF-focused development:
Overkill for PDF-Only Projects: GdPicture.NET SDK is a full document imaging suite including OCR, barcode recognition, scanning, and image processing. If you only need PDF functionality, you're paying for features you'll never use.
Complex Licensing: Multiple product tiers (GdPicture.NET 14, GdPicture.API, Ultimate, Professional) with confusing SKU combinations and annual subscription requirements.
Enterprise Pricing: License costs start at $2,999 for the PDF plugin alone, scaling to $10,000+ for the Ultimate edition. Per-developer licensing adds significant overhead for growing teams.
Steep Learning Curve: The API is designed around document imaging concepts, not modern .NET patterns. Methods like
LicenseManager.RegisterKEY(),GdPictureStatusenum checking, and 1-indexed pages feel dated compared to contemporary C# conventions.Status Code Pattern: Every operation returns a
GdPictureStatusenum that must be checked—no exceptions thrown on errors, making error handling verbose and repetitive.Manual Resource Management: Requires explicit
Dispose()orRelease()calls. The SDK doesn't follow standard .NET disposal patterns cleanly.Version Lock-in: The namespace
GdPicture14includes the version number, making major version upgrades require namespace changes throughout your entire codebase.- Rebranding Confusion: The recent rebrand to "Nutrient" creates documentation fragmentation between gdpicture.com and nutrient.io, complicating support and learning.
GdPicture.NET SDK vs IronPDF Comparison
| Aspect | GdPicture.NET SDK | IronPDF |
|---|---|---|
| Focus | Document imaging suite (overkill for PDF) | PDF-specific library |
| Pricing | $2,999-$10,000+ enterprise tier | Competitive, scales with business |
| API Style | Status codes, manual management | Exceptions, IDisposable, modern .NET |
| Learning Curve | Steep (imaging SDK concepts) | Simple (HTML/CSS familiar) |
| HTML Rendering | Basic, internal engine | Latest Chromium with CSS3/JS |
| Page Indexing | 1-indexed | 0-indexed (standard .NET) |
| Thread Safety | Manual synchronization required | Thread-safe by design |
| Namespace | Version-specific (GdPicture14) | Stable (IronPdf) |
For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF provides a future-proof foundation that aligns with modern .NET patterns and conventions.
Migration Complexity Assessment
Estimated Effort by Feature
| Feature | Migration Complexity | Notes |
|---|---|---|
| HTML to PDF | Low | Direct method mapping |
| URL to PDF | Low | Direct method mapping |
| Merge PDFs | Low | Similar API patterns |
| Split PDFs | Low | Similar API patterns |
| Watermarks | Low | Different approach (HTML-based) |
| Text Extraction | Low | Property vs method |
| Password Protection | Medium | Different parameter structure |
| Form Fields | Medium | API differences |
| Digital Signatures | Medium-High | Different certificate handling |
| OCR | High | IronOCR is separate product |
| Barcode Recognition | N/A | Not supported in IronPDF |
Migration Decision Matrix
| Your Situation | Recommendation |
|---|---|
| PDF-only operations | Migrate—significant simplification and cost savings |
| Heavy OCR usage | Consider IronOCR as companion product |
| Barcode/scanning needs | Keep GdPicture.NET SDK for those features, use IronPDF for PDF |
| Full document imaging | Evaluate if you actually use all features |
Before You Start
Prerequisites
- .NET Version: IronPDF supports .NET Framework 4.6.2+ and .NET Core 2.0+ / .NET 5/6/7/8/9+
- License Key: Obtain your IronPDF license key from ironpdf.com
- Backup: Create a branch for migration work
Identify All GdPicture.NET SDK Usage
# Find all GdPicture.NET SDK references in your codebase
grep -r "GdPicture14\|GdPicturePDF\|GdPictureDocumentConverter\|GdPictureStatus\|LicenseManager\.RegisterKEY" --include="*.cs" .
# Find all GdPicture package references
grep -r "GdPicture" --include="*.csproj" .# Find all GdPicture.NET SDK references in your codebase
grep -r "GdPicture14\|GdPicturePDF\|GdPictureDocumentConverter\|GdPictureStatus\|LicenseManager\.RegisterKEY" --include="*.cs" .
# Find all GdPicture package references
grep -r "GdPicture" --include="*.csproj" .NuGet Package Changes
# Remove GdPicture.NET SDK packages
dotnet remove package GdPicture.NET.14
dotnet remove package GdPicture.NET.14.API
dotnet remove package GdPicture
dotnet remove package GdPicture.API
# Install IronPDF
dotnet add package IronPdf# Remove GdPicture.NET SDK packages
dotnet remove package GdPicture.NET.14
dotnet remove package GdPicture.NET.14.API
dotnet remove package GdPicture
dotnet remove package GdPicture.API
# Install IronPDF
dotnet add package IronPdfQuick Start Migration
Step 1: Update License Configuration
Before (GdPicture.NET SDK):
// Must be called before any GdPicture.NET SDK operations
LicenseManager.RegisterKEY("YOUR-GDPICTURE-LICENSE-KEY");// Must be called before any GdPicture.NET SDK operations
LicenseManager.RegisterKEY("YOUR-GDPICTURE-LICENSE-KEY");After (IronPDF):
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or in appsettings.json:
// { "IronPdf.License.LicenseKey": "YOUR-LICENSE-KEY" }// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or in appsettings.json:
// { "IronPdf.License.LicenseKey": "YOUR-LICENSE-KEY" }Step 2: Update Namespace Imports
// Before (GdPicture.NET SDK)
using GdPicture14;
// After (IronPDF)
using IronPdf;
using IronPdf.Editing;// Before (GdPicture.NET SDK)
using GdPicture14;
// After (IronPDF)
using IronPdf;
using IronPdf.Editing;Step 3: Basic Conversion Pattern
The most significant change in the GdPicture.NET SDK migration is eliminating the verbose status-checking pattern:
Before (GdPicture.NET SDK):
using GdPicture14;
LicenseManager.RegisterKEY("LICENSE-KEY");
using (GdPictureDocumentConverter converter = new GdPictureDocumentConverter())
{
GdPictureStatus status = converter.LoadFromHTMLString("<h1>Hello World</h1>");
if (status == GdPictureStatus.OK)
{
status = converter.SaveAsPDF("output.pdf");
if (status != GdPictureStatus.OK)
{
Console.WriteLine($"Error: {status}");
}
}
else
{
Console.WriteLine($"Load error: {status}");
}
}using GdPicture14;
LicenseManager.RegisterKEY("LICENSE-KEY");
using (GdPictureDocumentConverter converter = new GdPictureDocumentConverter())
{
GdPictureStatus status = converter.LoadFromHTMLString("<h1>Hello World</h1>");
if (status == GdPictureStatus.OK)
{
status = converter.SaveAsPDF("output.pdf");
if (status != GdPictureStatus.OK)
{
Console.WriteLine($"Error: {status}");
}
}
else
{
Console.WriteLine($"Load error: {status}");
}
}After (IronPDF):
using IronPdf;
IronPdf.License.LicenseKey = "LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");using IronPdf;
IronPdf.License.LicenseKey = "LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");Key Differences:
- No status checking—exceptions on errors
- No explicit disposal required for renderer
- Modern fluent API
- Chromium-based rendering for better HTML/CSS support
Complete API Reference
Namespace Mapping
| GdPicture.NET SDK | IronPDF |
|---|---|
GdPicture14 | IronPdf |
GdPicture14.PDF | IronPdf |
GdPicture14.Imaging | N/A (not needed) |
Core Class Mapping
| GdPicture.NET SDK | IronPDF | Description |
|---|---|---|
GdPicturePDF | PdfDocument | Main PDF document class |
GdPictureDocumentConverter | ChromePdfRenderer | HTML/URL to PDF conversion |
LicenseManager | IronPdf.License | License management |
GdPictureStatus | Exceptions | Error handling |
Document Loading Methods
| GdPicture.NET SDK | IronPDF | Notes |
|---|---|---|
pdf.LoadFromFile(path, loadInMemory) | PdfDocument.FromFile(path) | Load from file |
pdf.LoadFromFile(path, password, loadInMemory) | PdfDocument.FromFile(path, password) | Password-protected |
converter.LoadFromHTMLString(html) | renderer.RenderHtmlAsPdf(html) | HTML string |
converter.LoadFromURL(url) | renderer.RenderUrlAsPdf(url) | URL |
Page Operations
| GdPicture.NET SDK | IronPDF | Notes |
|---|---|---|
pdf.GetPageCount() | pdf.PageCount | Get page count |
pdf.SelectPage(pageNo) | pdf.Pages[index] | Select page (1-indexed vs 0-indexed) |
pdf.GetPageWidth() | pdf.Pages[i].Width | Page width |
pdf.GetPageHeight() | pdf.Pages[i].Height | Page height |
Merge and Split Operations
| GdPicture.NET SDK | IronPDF | Notes |
|---|---|---|
pdf1.MergePages(pdf2) | PdfDocument.Merge(pdf1, pdf2) | Merge PDFs |
pdf.ExtractPages(start, end) | pdf.CopyPages(indices) | Extract pages |
Watermark Operations
| GdPicture.NET SDK | IronPDF | Notes |
|---|---|---|
pdf.DrawText(...) loop | pdf.ApplyWatermark(html) | Text watermark |
pdf.SetTextColor(color) | CSS styling | Set text color |
pdf.SetTextSize(size) | CSS styling | Set text size |
Code Migration Examples
Example 1: HTML to PDF Conversion
Before (GdPicture.NET SDK):
// NuGet: Install-Package GdPicture.NET
using GdPicture14;
using System;
class Program
{
static void Main()
{
using (GdPictureDocumentConverter converter = new GdPictureDocumentConverter())
{
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
GdPictureStatus status = converter.LoadFromHTMLString(htmlContent);
if (status == GdPictureStatus.OK)
{
converter.SaveAsPDF("output.pdf");
}
}
}
}// NuGet: Install-Package GdPicture.NET
using GdPicture14;
using System;
class Program
{
static void Main()
{
using (GdPictureDocumentConverter converter = new GdPictureDocumentConverter())
{
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
GdPictureStatus status = converter.LoadFromHTMLString(htmlContent);
if (status == GdPictureStatus.OK)
{
converter.SaveAsPDF("output.pdf");
}
}
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}IronPDF's ChromePdfRenderer uses a modern Chromium engine for accurate HTML/CSS rendering, eliminating the need for status code checking. For more HTML rendering options, see the HTML to PDF documentation.
Example 2: Merge Multiple PDFs
Before (GdPicture.NET SDK):
// NuGet: Install-Package GdPicture.NET
using GdPicture14;
using System;
class Program
{
static void Main()
{
using (GdPicturePDF pdf1 = new GdPicturePDF())
using (GdPicturePDF pdf2 = new GdPicturePDF())
{
pdf1.LoadFromFile("document1.pdf", false);
pdf2.LoadFromFile("document2.pdf", false);
pdf1.MergePages(pdf2);
pdf1.SaveToFile("merged.pdf");
}
}
}// NuGet: Install-Package GdPicture.NET
using GdPicture14;
using System;
class Program
{
static void Main()
{
using (GdPicturePDF pdf1 = new GdPicturePDF())
using (GdPicturePDF pdf2 = new GdPicturePDF())
{
pdf1.LoadFromFile("document1.pdf", false);
pdf2.LoadFromFile("document2.pdf", false);
pdf1.MergePages(pdf2);
pdf1.SaveToFile("merged.pdf");
}
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(new List<PdfDocument> { pdf1, pdf2 });
merged.SaveAs("merged.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(new List<PdfDocument> { pdf1, pdf2 });
merged.SaveAs("merged.pdf");
}
}IronPDF's static Merge method accepts a list of documents, making it easy to combine multiple PDFs in a single operation. Learn more about merging and splitting PDFs.
Example 3: Add Watermark to All Pages
Before (GdPicture.NET SDK):
// NuGet: Install-Package GdPicture.NET
using GdPicture14;
using System;
using System.Drawing;
class Program
{
static void Main()
{
using (GdPicturePDF pdf = new GdPicturePDF())
{
pdf.LoadFromFile("input.pdf", false);
for (int i = 1; i <= pdf.GetPageCount(); i++)
{
pdf.SelectPage(i);
pdf.SetTextColor(Color.Red);
pdf.SetTextSize(48);
pdf.DrawText("CONFIDENTIAL", 200, 400);
}
pdf.SaveToFile("watermarked.pdf");
}
}
}// NuGet: Install-Package GdPicture.NET
using GdPicture14;
using System;
using System.Drawing;
class Program
{
static void Main()
{
using (GdPicturePDF pdf = new GdPicturePDF())
{
pdf.LoadFromFile("input.pdf", false);
for (int i = 1; i <= pdf.GetPageCount(); i++)
{
pdf.SelectPage(i);
pdf.SetTextColor(Color.Red);
pdf.SetTextSize(48);
pdf.DrawText("CONFIDENTIAL", 200, 400);
}
pdf.SaveToFile("watermarked.pdf");
}
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
class Program
{
static void Main()
{
var pdf = PdfDocument.FromFile("input.pdf");
pdf.ApplyWatermark("<h1 style='color:red;'>CONFIDENTIAL</h1>", 50, 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("input.pdf");
pdf.ApplyWatermark("<h1 style='color:red;'>CONFIDENTIAL</h1>", 50, VerticalAlignment.Middle, HorizontalAlignment.Center);
pdf.SaveAs("watermarked.pdf");
}
}The GdPicture.NET SDK migration from coordinate-based text drawing to HTML-based watermarking simplifies code significantly. IronPDF's ApplyWatermark method uses HTML/CSS styling, eliminating the need for manual page iteration and coordinate calculations. See the complete watermarking documentation for additional options.
Example 4: Password Protection and Security
Before (GdPicture.NET SDK):
using GdPicture14;
class Program
{
static void Main()
{
LicenseManager.RegisterKEY("LICENSE-KEY");
using (GdPicturePDF pdf = new GdPicturePDF())
{
GdPictureStatus status = pdf.LoadFromFile("document.pdf", false);
if (status != GdPictureStatus.OK) return;
// Save with encryption - many boolean parameters
status = pdf.SaveToFile(
"protected.pdf",
PdfEncryption.PdfEncryption256BitAES,
"user123", // User password
"owner456", // Owner password
true, // Can print
false, // Cannot copy
false, // Cannot modify
false, // Cannot add notes
true, // Can fill forms
false, // Cannot extract
false, // Cannot assemble
true // Can print high quality
);
}
}
}using GdPicture14;
class Program
{
static void Main()
{
LicenseManager.RegisterKEY("LICENSE-KEY");
using (GdPicturePDF pdf = new GdPicturePDF())
{
GdPictureStatus status = pdf.LoadFromFile("document.pdf", false);
if (status != GdPictureStatus.OK) return;
// Save with encryption - many boolean parameters
status = pdf.SaveToFile(
"protected.pdf",
PdfEncryption.PdfEncryption256BitAES,
"user123", // User password
"owner456", // Owner password
true, // Can print
false, // Cannot copy
false, // Cannot modify
false, // Cannot add notes
true, // Can fill forms
false, // Cannot extract
false, // Cannot assemble
true // Can print high quality
);
}
}
}After (IronPDF):
using IronPdf;
class Program
{
static void Main()
{
var pdf = PdfDocument.FromFile("document.pdf");
// Configure security settings with clear property names
pdf.SecuritySettings.OwnerPassword = "owner456";
pdf.SecuritySettings.UserPassword = "user123";
// Set permissions
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SecuritySettings.AllowUserAnnotations = false;
pdf.SecuritySettings.AllowUserFormData = true;
pdf.SaveAs("protected.pdf");
}
}using IronPdf;
class Program
{
static void Main()
{
var pdf = PdfDocument.FromFile("document.pdf");
// Configure security settings with clear property names
pdf.SecuritySettings.OwnerPassword = "owner456";
pdf.SecuritySettings.UserPassword = "user123";
// Set permissions
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SecuritySettings.AllowUserAnnotations = false;
pdf.SecuritySettings.AllowUserFormData = true;
pdf.SaveAs("protected.pdf");
}
}IronPDF's SecuritySettings property provides named, self-documenting properties instead of positional boolean parameters.
Critical Migration Notes
Page Indexing Conversion
One of the most important changes in this GdPicture.NET SDK migration is the page indexing difference:
// GdPicture.NET SDK: 1-indexed pages
for (int i = 1; i <= pdf.GetPageCount(); i++)
{
pdf.SelectPage(i);
// process page
}
// IronPDF: 0-indexed pages (standard .NET)
for (int i = 0; i < pdf.PageCount; i++)
{
var page = pdf.Pages[i];
// process page
}// GdPicture.NET SDK: 1-indexed pages
for (int i = 1; i <= pdf.GetPageCount(); i++)
{
pdf.SelectPage(i);
// process page
}
// IronPDF: 0-indexed pages (standard .NET)
for (int i = 0; i < pdf.PageCount; i++)
{
var page = pdf.Pages[i];
// process page
}Status Codes to Exceptions
Replace verbose status checking with standard try-catch:
// GdPicture.NET SDK
GdPictureStatus status = converter.LoadFromHTMLString(html);
if (status != GdPictureStatus.OK)
{
Console.WriteLine($"Error: {status}");
return;
}
// IronPDF
try
{
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}// GdPicture.NET SDK
GdPictureStatus status = converter.LoadFromHTMLString(html);
if (status != GdPictureStatus.OK)
{
Console.WriteLine($"Error: {status}");
return;
}
// IronPDF
try
{
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}Unit Conversion
GdPicture.NET SDK uses inches for margins; IronPDF uses millimeters:
// GdPicture.NET SDK: 0.5 inches margin
converter.HtmlSetMargins(0.5f, 0.5f, 0.5f, 0.5f);
// IronPDF: 0.5 inches = 12.7 mm
renderer.RenderingOptions.MarginTop = 12.7;
renderer.RenderingOptions.MarginBottom = 12.7;
renderer.RenderingOptions.MarginLeft = 12.7;
renderer.RenderingOptions.MarginRight = 12.7;// GdPicture.NET SDK: 0.5 inches margin
converter.HtmlSetMargins(0.5f, 0.5f, 0.5f, 0.5f);
// IronPDF: 0.5 inches = 12.7 mm
renderer.RenderingOptions.MarginTop = 12.7;
renderer.RenderingOptions.MarginBottom = 12.7;
renderer.RenderingOptions.MarginLeft = 12.7;
renderer.RenderingOptions.MarginRight = 12.7;Conversion formula: millimeters = inches × 25.4
Thread Safety
GdPicture.NET SDK requires manual synchronization for concurrent operations. IronPDF's ChromePdfRenderer is thread-safe by design, simplifying multi-threaded PDF generation.
Performance Considerations
Reuse ChromePdfRenderer
For optimal performance, reuse the renderer instance:
// GOOD - Reuse renderer (thread-safe)
public class PdfService
{
private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();
public byte[] Generate(string html) => _renderer.RenderHtmlAsPdf(html).BinaryData;
}
// BAD - Creates new instance each time
public byte[] GenerateBad(string html)
{
var renderer = new ChromePdfRenderer(); // Wasteful
return renderer.RenderHtmlAsPdf(html).BinaryData;
}// GOOD - Reuse renderer (thread-safe)
public class PdfService
{
private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();
public byte[] Generate(string html) => _renderer.RenderHtmlAsPdf(html).BinaryData;
}
// BAD - Creates new instance each time
public byte[] GenerateBad(string html)
{
var renderer = new ChromePdfRenderer(); // Wasteful
return renderer.RenderHtmlAsPdf(html).BinaryData;
}Proper Resource Disposal
// Use using statements for automatic cleanup
using (var pdf = PdfDocument.FromFile("large.pdf"))
{
string text = pdf.ExtractAllText();
} // pdf is disposed automatically// Use using statements for automatic cleanup
using (var pdf = PdfDocument.FromFile("large.pdf"))
{
string text = pdf.ExtractAllText();
} // pdf is disposed automaticallyMigration Checklist
Pre-Migration
- Inventory all GdPicture.NET SDK usage in codebase
- Identify which features are actually used (PDF vs OCR vs barcode)
- Determine if OCR/barcode features are needed (consider IronOCR/IronBarcode)
- Review current licensing and compare to IronPDF pricing
- Obtain IronPDF license key
- Create migration branch in version control
Code Migration
- Remove GdPicture.NET SDK NuGet packages:
dotnet remove package GdPicture.NET - Install IronPdf NuGet package:
dotnet add package IronPdf - Update namespace imports (
GdPicture14→IronPdf) - Replace
LicenseManager.RegisterKEY()withIronPdf.License.LicenseKey - Convert status code checks to try-catch blocks
- Update page indexing (1-indexed → 0-indexed)
- Replace
GdPicturePDFwithPdfDocument - Replace
GdPictureDocumentConverterwithChromePdfRenderer - Convert coordinate-based text to HTML stamping
- Update unit conversions (inches → millimeters)
Testing
- Unit test all PDF generation paths
- Verify HTML rendering quality matches or exceeds
- Test all security/encryption scenarios
- Verify form filling functionality
- Test merge/split operations
- Validate watermark appearance
- Performance benchmark critical paths
Post-Migration
- Remove GdPicture.NET SDK license files/keys
- Update documentation
- Train team on IronPDF API patterns
- Monitor production for any issues






