PDF to image, the conversion of PDF pages to images, is one of the most requested features and it is now available in XFINIUM.PDF 5.0 Professional Edition.
We have implemented the conversion of PDF pages to images through our custom Xfinium.Graphics PDF rendering engine. It has been developed from scratch and it has been developed to be cross-platform. This allowed us to support PDF to image capabilities on all platforms.
The conversion of a PDF page to image is a simple 3 step process:
– load the document
– create a renderer for the page
– convert the page to image
PdfFixedDocument doc = new PdfFixedDocument("sample.pdf"); PdfPageRenderer renderer = new PdfPageRenderer(doc.Pages[0]); Bitmap pageImage = renderer.ConvertPageToImage(96);
Dim doc As New PdfFixedDocument("sample.pdf") Dim renderer As New PdfPageRenderer(doc.Pages(0)) Dim pageImage As Bitmap = renderer.ConvertPageToImage(96)
The library supports converting PDF pages to RAW images.
PdfFixedDocument doc = new PdfFixedDocument("sample.pdf"); PdfPageRenderer renderer = new PdfPageRenderer(doc.Pages[0]); FileStream rawStream = File.OpenWrite("sample.raw"); renderer.ConvertPageToImage(96, rawStream, PdfPageImageFormat.Raw); rawStream.Flush(); rawStream.Close();
Dim doc As New PdfFixedDocument("sample.pdf") Dim renderer As New PdfPageRenderer(doc.Pages(0)) Dim rawStream As FileStream = File.OpenWrite("sample.raw") renderer.ConvertPageToImage(96, rawStream, PdfPageImageFormat.Raw) rawStream.Flush() rawStream.Close()
For RAW images the RGBA layout is used by default but the library provides support for RGBA, BGRA and ARGB rendering surfaces in case you need different color layout.
The code below uses an ARGB rendering surface for converting the PDF to image.
PdfFixedDocument doc = new PdfFixedDocument("sample.pdf"); PdfPageRenderer renderer = new PdfPageRenderer(doc.Pages[0]); PdfRendererSettings settings = new PdfRendererSettings(); settings.DpiX = settings.DpiY = 96; settings.RenderingSurface = renderer.CreateRenderingSurface<PdfArgbByteRenderingSurface>(settings.DpiX, settings.DpiY); FileStream rawStream = File.OpenWrite("sample.raw"); renderer.ConvertPageToImage(rawStream, PdfPageImageFormat.Raw, settings); rawStream.Flush(); rawStream.Close();
Dim doc As New PdfFixedDocument("sample.pdf") Dim renderer As New PdfPageRenderer(doc.Pages(0)) Dim settings As New PdfRendererSettings() settings.DpiX = InlineAssignHelper(settings.DpiY, 96) settings.RenderingSurface = renderer.CreateRenderingSurface(Of PdfArgbByteRenderingSurface)(settings.DpiX, settings.DpiY) Dim rawStream As FileStream = File.OpenWrite("sample.raw") renderer.ConvertPageToImage(rawStream, PdfPageImageFormat.Raw, settings) rawStream.Flush() rawStream.Close()
The rendering surface can use either an array of bytes or an array of integers as storage. You select the appropriate storage based on what you want to do with the rendered image.
For example if you’re working with WriteableBitmaps in Silverlight you should use an int based storage because it will be easier to transfer the pixels from the rendering surface to the WriteableBitmap.
PdfFixedDocument doc = new PdfFixedDocument("sample.pdf"); PdfPageRenderer renderer = new PdfPageRenderer(doc.Pages[0]); PdfRendererSettings settings = new PdfRendererSettings(); settings.DpiX = settings.DpiY = 96; PdfArgbIntRenderingSurface rs = renderer.CreateRenderingSurface<PdfArgbIntRenderingSurface>(settings.DpiX, settings.DpiY); settings.RenderingSurface = rs; renderer.ConvertPageToImage(settings); WriteableBitmap wb = new WriteableBitmap(rs.Width, rs.Height); Array.Copy(rs.Bitmap, wb.Pixels, rs.Bitmap.Length);
Dim doc As New PdfFixedDocument("sample.pdf") Dim renderer As New PdfPageRenderer(doc.Pages(0)) Dim settings As New PdfRendererSettings() settings.DpiX = InlineAssignHelper(settings.DpiY, 96) Dim rs As PdfArgbIntRenderingSurface = renderer.CreateRenderingSurface(Of PdfArgbIntRenderingSurface)(settings.DpiX, settings.DpiY) settings.RenderingSurface = rs renderer.ConvertPageToImage(settings) Dim wb As New WriteableBitmap(rs.Width, rs.Height) Array.Copy(rs.Bitmap, wb.Pixels, rs.Bitmap.Length)
The PDF rendering engine is portable and this means almost identical results on all platforms. Why almost? The PDF rendering engine compiled for Windows Forms and WPF has access to the fonts installed on the local machine. If the PDF files use non-embedded fonts then the WinForms and WPF versions will retrieve the fonts from the local machine while the other versions will use a default Helvetica font.
Fell free to contact us with any questions you might have about PDF rendering or if you have a PDF file that is not rendered correctly.
Hey,
I’m using below code to open pdf, convert it to image and return as byte array. I do it on Xamarin.iOS and use the byte array as Image source to show it, sadly I get only white image, nothing else. The array is not empty, I get no exceptions:
PdfFixedDocument doc = new PdfFixedDocument(NSBundle.MainBundle.BundlePath + “/” + path);
PdfPageRenderer renderer = new PdfPageRenderer(doc.Pages[0]);
var pageImage = renderer.ConvertPageToImage(96);
return pageImage.DataProvider.CopyData().ToArray();
do you have any idea? I’d love to buy your product after I get a working proof of concept
Cheers,
Michał
Please send us (support@xfiniumpdf.com) the PDF file and we’ll investigate this problem.
Thanks for replying. It happens with any pdf I tried, even when the whole pdf is black, I get white image.
Maybe my method to het the byte array from iOS project to PCL project is wrong?
Can you send us your full test project so we can take a look at it?
Is there any tutorial how to use it in Xamarin Forms project?
Do you also suppport converting PDF files to PNG images on Mono?
Yes, we support this functionality on Mono. The xfinium.pdf.mono.dll and xfinium.pdf.render.mono.dll can be used with Mono.
How to render page to target size (in pixels) instead dpi?
Example:
PdfBgraByteRenderingSurface renderingSurface = new PdfBgraByteRenderingSurface(decodeWidth, decodeHeight);
PdfRendererSettings rendererSettings = new PdfRendererSettings();
rendererSettings.BackgroundColor = -1;
rendererSettings.RenderAnnotations = false;
rendererSettings.RenderingSurface = renderingSurface;
PdfPage page = doc.Pages[pageNum – 1];
PdfPageRenderer renderer = new PdfPageRenderer(page);
var size = renderer.ConvertPageToImage(rendererSettings);
return renderingSurface.Bitmap;
I get a completely different final size and as a consequence, a completely different bitmap resolution.
And an additional question: how to render part of the page (target rectangle)?
P.S. I tried .NET Standard on UWP.
The page is always rendered to image based on provided dpi. If you need a specific size in pixels for the output image, you can compute the dpi so that the output image has the desired size.
pageSizeInPoints * dpi / 72 = sizeOfRenderedPageImageInPixels
If you want to render only a part of the page you can set the page CropBox to desired area and then render the page.