Add the RecursiveAI.OneImage.Pdf package, register PdfFormat in the load options, and load the PDF: each page is a frame. Save Frames[i].ToImage() as .png or .jpg. There is no PDFium, Ghostscript or other native binary to deploy. The program below renders every page of the IRS Form W-9, a public six-page PDF.
dotnet new console -o PdfToImage && cd PdfToImage dotnet add package RecursiveAI.OneImage.Pdf --version 1.10.4 curl -LO https://www.irs.gov/pub/irs-pdf/fw9.pdf
OneImage needs the .NET 10 SDK. Put this in Program.cs and run dotnet run:
using OneImage; using OneImage.Pdf; // PDF is an add-on format: register it, 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); // reads the structure, draws nothing Console.WriteLine($"{pdf.FrameCount} pages"); for (int i = 0; i < pdf.FrameCount; i++) { Image page = pdf.Frames[i].ToImage(); page.Save($"page-{i + 1}.png"); Console.WriteLine($"page-{i + 1}.png: {page.Width}x{page.Height}"); }
6 pages page-1.png: 1275x1650 page-2.png: 1275x1650 page-3.png: 1275x1650 page-4.png: 1275x1650 page-5.png: 1275x1650 page-6.png: 1275x1650
A US Letter page is 612×792 points, so at 150 dpi it is 1275×1650 pixels: points × dpi ÷ 72. Pages are drawn on opaque white, as viewers show them. The output format follows the extension, so .jpg and .webp work the same way.
One page at 300 dpi, and a thumbnail
To render only some pages, set FirstPage (zero-based) and PageCount. A resize right after the load draws the page at the final size instead of drawing it large and shrinking it:
using OneImage; using OneImage.Pdf; // Page 1 only, at 300 dpi, as JPEG. var page1 = new LoadOptions { Configuration = new ImageConfiguration().Add(new PdfFormat( new PdfRenderOptions { Dpi = 300, FirstPage = 0, PageCount = 1 })), }; Image.Load("fw9.pdf", page1).Save("page-1-300dpi.jpg", new SaveOptions { EncoderOptions = new JpegEncoderOptions { Quality = 85 }, }); // A 300 px wide WebP thumbnail of the first page. Image.Thumbnail("fw9.pdf", 300, loadOptions: page1).Save("cover.webp"); foreach (string file in new[] { "page-1-300dpi.jpg", "cover.webp" }) { ImageInfo info = Image.Identify(file); long kb = new FileInfo(file).Length / 1024; Console.WriteLine($"{file}: {info.Width}x{info.Height}, {kb} KB"); }
page-1-300dpi.jpg: 2550x3300, 1186 KB cover.webp: 300x388, 21 KB
Dpi | US Letter in pixels | Typical use |
|---|---|---|
| 72 | 612×792 | Previews |
| 150 (default) | 1275×1650 | Readable page images |
| 300 | 2550×3300 | OCR and print-quality archives |
PdfRenderOptions also sets the page box, whether annotations are drawn, a transparent Background, and the Password of an encrypted file.
Limits
- It renders pixels only. To get the text out of a PDF, see Extract text from a PDF in OnePDF.
- Untrusted files are bounded. File size, page size, image pixels and nesting depth are checked from the file before memory is allocated; a file over a limit throws
ImageLimitException. The limits table has the defaults. - JPEG and BMP hold one page. Saving the whole document as
.jpgwrites page 1 only; loop overFrames, or save a multipage TIFF. - .NET 10 only. PDFtoImage (MIT) wraps native PDFium and supports older frameworks.
How pages are drawn and checked is in the OneImage.Pdf docs.