PNG-to-PDF in .NET is about embedding a raster image into a PDF container. iText 7 is the full-featured option — control page dimensions, image scaling, and document properties. PdfSharp is a lightweight MIT-licensed alternative for simpler use cases. The ChangeThisFile API handles it server-side via a single POST when you don't want a PDF library in your dependency tree.

Method 1: iText 7 (precise layout, multi-image PDF)

iText 7 is the most capable PDF library in .NET. Fine-grained control over page size, image placement, compression, and metadata.

dotnet add package itext7
using iText.IO.Image;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;

public static class PngToPdf
{
    /// <summary>Converts one or more PNG files into a single PDF.</summary>
    public static void Convert(
        IEnumerable<string> pngPaths,
        string outputPath,
        bool fitToImage = true)
    {
        using var writer = new PdfWriter(outputPath);
        using var pdfDoc = new PdfDocument(writer);
        using var doc = new Document(pdfDoc);

        doc.SetMargins(0, 0, 0, 0);

        foreach (var pngPath in pngPaths)
        {
            var imageData = ImageDataFactory.Create(pngPath);
            var image = new iText.Layout.Element.Image(imageData);

            if (fitToImage)
            {
                // Make each page exactly the size of the image
                var pageSize = new PageSize(
                    imageData.GetWidth(), imageData.GetHeight());
                pdfDoc.AddNewPage(pageSize);
                image.SetFixedPosition(
                    pdfDoc.GetNumberOfPages(), 0, 0);
                image.SetWidth(UnitValue.CreatePointValue(imageData.GetWidth()));
            }
            else
            {
                // A4 page with auto-scaled image
                pdfDoc.AddNewPage(PageSize.A4);
                image.SetAutoScale(true);
            }

            doc.Add(image);
        }
    }
}

// Single PNG
PngToPdf.Convert(new[] { "image.png" }, "image.pdf");

// Multiple PNGs in one PDF
PngToPdf.Convert(new[] { "page1.png", "page2.png", "page3.png" }, "document.pdf");

iText 7 is AGPL — free for open-source projects. Commercial use without open-sourcing your code requires an iText license. For MIT-licensed alternatives, see PdfSharp below.

Method 2: PdfSharp (MIT license, simpler API)

PdfSharp is fully MIT-licensed and handles standard PNG-to-PDF without the AGPL concern. Less feature-rich than iText but sufficient for most image-to-PDF needs.

dotnet add package PdfSharp
using PdfSharp.Drawing;
using PdfSharp.Pdf;

public static class PngToPdfSharp
{
    public static void Convert(
        IEnumerable<string> pngPaths,
        string outputPath)
    {
        using var document = new PdfDocument();
        document.Info.Title = "Converted Images";

        foreach (var pngPath in pngPaths)
        {
            using var xImage = XImage.FromFile(pngPath);

            // Create a page the exact size of the image
            var page = document.AddPage();
            page.Width = XUnit.FromPoint(xImage.PointWidth);
            page.Height = XUnit.FromPoint(xImage.PointHeight);

            using var gfx = XGraphics.FromPdfPage(page);
            gfx.DrawImage(xImage, 0, 0, page.Width, page.Height);
        }

        document.Save(outputPath);
    }
}

PdfSharp 6+ adds .NET 6/7/8 support. Use the NuGet package PdfSharp (not the older PdfSharp-WPF) for cross-platform compatibility.

Method 3: ChangeThisFile API (HttpClient, no PDF library)

POST the PNG, receive a PDF. Free tier: 1,000 conversions/month.

# Verify with curl first
curl -X POST https://changethisfile.com/v1/convert \
  -H "Authorization: Bearer ctf_sk_your_key" \
  -F "file=@image.png" \
  -F "target=pdf" \
  --output image.pdf
using System.Net.Http;
using System.Net.Http.Headers;

public class PdfConvertService
{
    private readonly HttpClient _http;
    private const string ApiKey = "ctf_sk_your_key_here";

    public PdfConvertService(IHttpClientFactory factory)
        => _http = factory.CreateClient("ctf");

    public async Task ConvertPngToPdfAsync(
        string pngPath,
        string pdfPath,
        CancellationToken ct = default)
    {
        await using var fileStream = File.OpenRead(pngPath);
        using var form = new MultipartFormDataContent();

        var fileContent = new StreamContent(fileStream);
        fileContent.Headers.ContentType =
            new MediaTypeHeaderValue("image/png");
        form.Add(fileContent, "file", Path.GetFileName(pngPath));
        form.Add(new StringContent("pdf"), "target");

        using var request = new HttpRequestMessage(HttpMethod.Post, "/v1/convert")
        {
            Content = form,
            Headers = { Authorization =
                new AuthenticationHeaderValue("Bearer", ApiKey) }
        };

        using var response = await _http.SendAsync(request, ct);
        response.EnsureSuccessStatusCode();

        await using var outStream = File.Create(pdfPath);
        await response.Content.CopyToAsync(outStream, ct);
    }
}

When to use each

ApproachBest forTradeoff
iText 7Multi-image PDFs, custom page sizes, document metadataAGPL — commercial use requires iText license
PdfSharpSimple image-to-PDF, MIT license, no licensing concernLess feature-rich than iText; no HTML renderer
ChangeThisFile APINo PDF library dep, single-image conversions, free tierNetwork call; 25MB file limit on free tier; one image per call

Production tips

  • Use IHttpClientFactory for the API. Register a named client in Program.cs and inject IHttpClientFactory — avoids socket exhaustion on high-volume endpoints.
  • Pass CancellationToken through all async calls. Wire it from HttpContext.RequestAborted in ASP.NET controllers so cancelled requests clean up correctly.
  • Set margins to zero for image-sized pages. iText and PdfSharp both default to margins. Set them to zero when you want the PDF page to be exactly the image size.
  • Dispose XImage properly in PdfSharp. XImage holds a GDI+ handle on Windows. Always use using var xImage = XImage.FromFile(path) — leaking XImage objects causes GDI handle exhaustion on long-running processes.
  • Consider compression. PDFs embedding large PNGs can be huge. iText 7 compresses image streams by default. For PdfSharp, ensure the PDF is saved with compression enabled (the default).

PdfSharp is the cleanest choice for most .NET projects — MIT license, simple API, cross-platform. iText 7 is the better option when you need multi-image layouts, document metadata, or more PDF control. The ChangeThisFile API removes both dependencies for single-image conversions. Free tier: 1,000 conversions/month.