Convert a PDF to an image in C#
Convert PDF pages to PNG, JPG or WebP in C# with pure .NET code: one page or all, DPI, thumbnails and ASP.NET Core uploads, with no PDFium or native binaries.
To convert a PDF to an image in C#, add the RecursiveAI.OneImage.Pdf package, register its PDF format, load the file and save a page as PNG or JPG. Each page becomes a frame of an ordinary OneImage Image, so the same code that resizes and converts photos also handles PDF pages. It is pure C# with no PDFium, Ghostscript or other native binaries to install, so it runs unchanged on Windows, Linux, macOS and in containers. The rest of this page covers single pages, whole documents, DPI, thumbnails, multi-page TIFF and ASP.NET Core uploads. Every sample was run against OneImage 1.6.0 and OneImage.Pdf 1.6.0 on .NET 10.
Before you start
- .NET 10. OneImage and its PDF package target
net10.0, so your project needs the .NET 10 SDK and anet10.0(or later) target framework. - One package. RecursiveAI.OneImage.Pdf brings in OneImage itself and the PDF engine it draws with, OnePdf and OnePdf.Fonts.
- License. OneImage, OneImage.Pdf and OnePdf are MIT OR Apache-2.0. OnePdf.Fonts adds OFL-1.1 for the fonts it bundles, as its NuGet listing states.
dotnet add package RecursiveAI.OneImage.Pdf
The examples use IRS Form W-9 (Rev. March 2024), a six-page US Letter PDF, so you can run them on the same file.
Convert the first page of a PDF to PNG
using OneImage; using OneImage.Pdf; // Register the PDF format: each page becomes a frame, drawn at 150 dpi. var options = new LoadOptions { Configuration = new ImageConfiguration() .Add(new PdfFormat(new PdfRenderOptions { Dpi = 150 })) }; Image pdf = Image.Load("fw9.pdf", options); pdf.Frames[0].ToImage().Save("page-1.png");
This writes a 1275×1650 PNG of the first page. PDF support lives in a separate package, so it isn’t in OneImage’s default configuration; you add PdfFormat to a configuration and pass it in LoadOptions. Like every OneImage operation, loading is lazy: nothing is drawn until you save.
The output format follows the file extension. Save as page-1.webp, .jpg, .tif, .gif or .bmp instead and nothing else changes.
Convert every page of a PDF to PNG
using OneImage; using OneImage.Pdf; var options = new LoadOptions { Configuration = new ImageConfiguration() .Add(new PdfFormat(new PdfRenderOptions { Dpi = 150 })) }; Image pdf = Image.Load("fw9.pdf", options); for (int i = 0; i < pdf.Frames.Count; i++) { pdf.Frames[i].ToImage().Save($"page-{i + 1}.png"); }
On the W-9 this writes page-1.png to page-6.png, each 1275×1650.
Convert one PDF page to JPG at 300 dpi
To render a single page, select it with FirstPage and PageCount rather than loading everything. FirstPage is zero-based.
using OneImage; using OneImage.Pdf; // Page 2 only (FirstPage is zero-based), at 300 dpi. var render = new PdfRenderOptions { Dpi = 300, FirstPage = 1, PageCount = 1 }; var options = new LoadOptions { Configuration = new ImageConfiguration().Add(new PdfFormat(render)) }; Image.Load("fw9.pdf", options).Save("page-2.jpg", new SaveOptions { EncoderOptions = new JpegEncoderOptions { Quality = 85 } });
The result is a 2550×3300 JPEG of 1.6 MB. JPEG has no transparency, and that’s fine here: pages are drawn on opaque white by default, as PDF viewers show them.
Choose the DPI
The pixel size of a page is its size in points (1/72 inch) times Dpi / 72, rounded to the nearest pixel. A US Letter page is 612×792 points:
Dpi | US Letter in pixels | Typical use |
|---|---|---|
| 72 | 612×792 | Previews and lists |
| 96 | 816×1056 | On-screen at 100% in most viewers |
| 150 (default) | 1275×1650 | Readable page images, document viewers |
| 300 | 2550×3300 | OCR input and print-quality archives |
Pixel count grows with the square of the DPI, so 300 dpi pages hold four times the pixels of 150 dpi pages. If you need a fixed width rather than a resolution, resize instead, as the next section shows.
Make a PDF thumbnail
using OneImage; using OneImage.Pdf; var options = new LoadOptions { Configuration = new ImageConfiguration() .Add(new PdfFormat(new PdfRenderOptions { PageCount = 1 })) }; // The page is drawn at 300 px wide, not rendered large and scaled down. Image.Thumbnail("fw9.pdf", 300, loadOptions: options).Save("cover.webp");
This writes a 300×388 WebP of the cover page. When a resize sits directly on a loaded PDF, OneImage draws the page at the final size instead of drawing it at the DPI and shrinking it, so text and lines stay sharp and no full-size bitmap is made. Image.Load(...).Resize(width: 300) works the same way. Image.Thumbnail takes a height and a fit: too, for fixed boxes; our guide to resizing images in C# covers the options.
Convert a PDF to a multi-page TIFF
using OneImage; using OneImage.Pdf; var options = new LoadOptions { Configuration = new ImageConfiguration() .Add(new PdfFormat(new PdfRenderOptions { Dpi = 200 })) }; // Every page, one TIFF file. Image.Load("fw9.pdf", options).Save("fw9.tif");
Saving the whole document writes every page into a format that holds several: the W-9 became a six-page TIFF of 1700×2200 pages. Formats with a single image, such as JPEG and BMP, get the first page only, so loop over Frames for those.
Count the pages without rendering
using OneImage; using OneImage.Pdf; var options = new LoadOptions { Configuration = new ImageConfiguration() .Add(new PdfFormat(new PdfRenderOptions { Dpi = 150 })) }; ImageInfo info = Image.Identify("fw9.pdf", options); Console.WriteLine($"{info.Frames.Count} pages, first page {info.Width}x{info.Height} px at 150 dpi");
It prints 6 pages, first page 1275x1650 px at 150 dpi without drawing anything, which is useful for validating uploads or building a page picker.
Convert an uploaded PDF to an image in ASP.NET Core
Loading also accepts a Stream or a byte array. This minimal API endpoint takes an uploaded PDF and returns a PNG preview of its first page, 800 px wide:
using OneImage; using OneImage.Pdf; var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); // Only PDF is registered, and only the first page is drawn. var pdfLoad = new LoadOptions { Configuration = new ImageConfiguration() .Add(new PdfFormat(new PdfRenderOptions { PageCount = 1 })) }; app.MapPost("/preview", async (IFormFile file) => { try { await using Stream upload = file.OpenReadStream(); Image preview = Image.Thumbnail(upload, 800, loadOptions: pdfLoad); var png = new MemoryStream(); await preview.SaveAsync(png, PngFormat.Instance); png.Position = 0; return Results.File(png, "image/png"); } catch (ImageException ex) // not a PDF, damaged, or over the limits { return Results.BadRequest(ex.Message); } }).DisableAntiforgery(); app.Run();
Posting the 2025 Form 1040 returned an 800×1035 PNG with its form fields and check boxes drawn. Because the configuration registers only PdfFormat, any other upload is refused: a PNG got a 400 with “The data is not in a recognized image format.” A stream has no file extension, so SaveAsync names the output format with PngFormat.Instance.
Uploaded PDFs are untrusted input. OneImage.Pdf checks its limits (file size, frame size, embedded image pixels, nesting depth and others) against the values the file declares, before memory is allocated, and a file over a limit fails with ImageLimitException, which is an ImageException. The limits table lists each default.
Render options
Everything is set on PdfRenderOptions, and every member has a default:
| Option | Default | What it does |
|---|---|---|
Dpi | 150 | Resolution of the page’s natural size. A resize directly on the loaded image draws at the final size instead. |
FirstPage, PageCount | 0, all | Which pages become frames. FirstPage is zero-based. |
Box | crop box | Which page box is drawn: PdfPageBox.CropBox, MediaBox, BleedBox, TrimBox or ArtBox. |
Annotations | view | Draw annotations as on screen (View), as printed (Print) or not at all (None). |
GenerateAppearances | true | Draw form fields and markup that have no stored appearance, as viewers do. |
Background | opaque white | The color the page is drawn on. Pass a transparent Rgba32 to get the page content alone, then save as PNG or WebP. |
Password | none | The password of an encrypted document. |
Limits | see docs | Bounds on what drawing one file may cost. |
The OneImage.Pdf documentation describes how pages are drawn. In short, the renderer covers vector paths, shadings, tiling patterns, soft masks, transparency groups and blend modes, and it decodes the JPEG, JBIG2 and JPEG 2000 images that scanned and archival PDFs often contain. Color is converted from gray, RGB, CMYK and ICC-based spaces. Pages are drawn in 128×128 cells, so a region of a page is the same pixels as that part of a whole-page render.
It runs in a plain container
Because nothing native is involved, there are no apt-get lines to add to your Dockerfile. We published the all-pages sample above and ran it in the stock mcr.microsoft.com/dotnet/runtime:10.0 image (Ubuntu 24.04) with nothing installed. It wrote the same six PNGs, byte for byte, as on the host, and the publish folder contained no native libraries.
Other ways to convert PDF to image in C#
- PDFtoImage 5.4.0 (August 2026) is MIT licensed and wraps native libraries. Its NuGet listing shows dependencies on SkiaSharp and its native asset packages and on per-platform PDFium binaries (for example bblanchon.PDFium.Linux). It targets more frameworks than OneImage, including .NET Framework 4.7.1, .NET 8 and mobile platforms, so it’s the choice if you can’t move to .NET 10.
- Commercial PDF SDKs such as IronPdf and GemBox.Pdf also render pages to images, under their vendors’ license terms (IronPDF licensing, GemBox.Pdf price list). They are broader PDF toolkits that also create and edit documents. OneImage.Pdf only renders pages.
- Command-line tools such as
pdftoppmor Ghostscript work if you shell out, but you then deploy and patch a separate binary and manage processes and temporary files.
For OneImage’s other formats and operations, see the overview. To turn the rendered pages into smaller web images, our guide to converting images to WebP in C# covers quality settings.