This guide shows how to convert PDF to image files, PNG or JPEG, with RadaeePDF on a server, on Android and on iOS.
Applies to: RadaeePDF Server SDK (CLI, Java, C#), RadaeePDF Master for Android, and RadaeePDF Master for iOS.
Key takeaways:
- To convert PDF to image with RadaeePDF, render each page into a pixel buffer with a matrix, then encode it as PNG or JPEG.
- On a server you can do it without code using the
rdpageCLI, or from Java and C#. - Use a scale of
dpi / 72: about 2.0 for previews and 4.17 for 300 dpi OCR images. - Transparent backgrounds need PNG output; JPEG has no alpha channel.
Turning PDF pages into images is one of the most requested tasks in the RadaeePDF knowledge base. Typical uses are document previews in a web portal, thumbnails in a file list, page images for an OCR or indexing step, and archives that must be readable without a PDF viewer.
Many developers know RadaeePDF as a mobile viewer, but the same native engine also ships as a Server SDK for Windows and Linux. It runs headless and is meant for conversions, editing and content manipulation on a server: rendering pages to bitmaps, extracting text, encrypting, merging, splitting and stamping documents. This article starts on the server, then shows the equivalent code for Android and iOS.
How to convert PDF to image: the rendering model
All editions follow the same model:
- Open a
Documentand get aPageobject for a 0-based page number. - Allocate a pixel buffer: a
BufferedImageorint[]array (Server Java), anRDDIB(Server C#), aBitmap(Android) or anRDPDFDIB(iOS). - Build a
Matrixthat maps PDF coordinates to pixels and render into the buffer. - Encode the pixels as PNG or JPEG, then close the page and the document.
The matrix needs a little attention. PDF coordinates start at the bottom-left corner, while bitmaps start at the top-left. As the Matrix source explains, the usual values are scale for x, -scale for y, and pageHeight * scale as the y offset. A scale of 1.0 renders at the page’s native size, 72 dpi, so 2.0 gives 144 dpi.
Choosing a resolution
Because page sizes are expressed in points (1/72 inch), the scale for a target resolution is simply dpi / 72. A few practical reference points:
- Thumbnails for a file list or page strip: a scale between 0.25 and 0.5, or a fixed longest side such as 200 pixels.
- On-screen previews in a web page: 1.5 to 2.0 (108 to 144 dpi) is usually sharp enough on high-density displays.
- OCR or print-quality archives: scale up to 300 dpi (about 4.17), and keep the output in PNG to avoid compression artifacts around text.
Remember that a 32-bit buffer costs 4 bytes per pixel. An A4 page (595 x 842 points) rendered at scale 2.0 is 1190 x 1684 pixels, about 8 MB before encoding. A server that converts several documents in parallel needs that amount for every page being rendered at the same time.
Server side: convert without writing code
The rdpage tool in the Server SDK’s CLI folder renders pages directly. Use a dpi of 72 for 100% and 144 for 200%:
./rdpage -out test.pdf "" png 108 0/test001.png 1/test002.png
# Export every page as JPEG at 200% into the "test" folder (0000.jpg, 0001.jpg, ...)
./rdpage -exp test.pdf "" jpg 144 test
The second argument is the document password ("" when there is none). Keep libRDDJni.so (or RDDJni.dll), cmaps.dat and umaps.dat in the same folder as the executable. If the tool reports “license not activated”, run ./rdinfo -r to get a request code and put the key you receive in key.txt next to the tools.
Server side: Java
The Java bindings in java/PDFJniDemo render into a standard java.awt.image.BufferedImage through Page.RenderToBuf(BufferedImage bimg, int back_clr, Matrix mat), so the result can go straight to javax.imageio.ImageIO. The method below is modeled on the JSP demo images.jsp. Its size parameter, the length of the longest side in pixels, comes from the knowledge base converter. The method also keeps the JSP demo’s 4096-pixel cap.
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.radaee.comm.Global;
import com.radaee.comm.Matrix;
import com.radaee.pdf.Document;
import com.radaee.pdf.Page;
public class PdfToImages {
/**
* @param size longest side in pixels, 0 = native size (72 dpi)
* @param png true for PNG, false for JPEG
* @param transparent PNG only: keep the page background transparent
* @return 0 on success, or the Document.Open error code
* (-1 password, -2 unknown encryption, -3 damaged, -10 access denied)
*/
public static int convert(String pdfPath, String password, File outDir,
int size, boolean png, boolean transparent) throws IOException {
Document doc = new Document();
int result = doc.Open(pdfPath, password);
if (result != 0) return result;
outDir.mkdirs();
try {
int count = doc.GetPageCount();
for (int i = 0; i < count; i++) {
Page page = doc.GetPage(i);
if (page == null) break; // license not activated
float pw = doc.GetPageWidth(i);
float ph = doc.GetPageHeight(i);
float scale = (size > 0) ? size / Math.max(pw, ph) : 1.0f;
if (pw * scale > 4096.0f) scale = 4096.0f / pw;
if (ph * scale > 4096.0f) scale = 4096.0f / ph;
int iw = Math.max(1, (int) (pw * scale + 0.5f));
int ih = Math.max(1, (int) (ph * scale + 0.5f));
BufferedImage bimg = new BufferedImage(iw, ih,
png ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
Matrix mat = new Matrix(scale, -scale, 0, ph * scale);
int background = (png && transparent) ? 0x00000000 : 0xFFFFFFFF;
boolean ok = page.RenderToBuf(bimg, background, mat);
mat.Destroy();
page.Close();
if (ok) {
String name = String.format("page_%04d.%s", i, png ? "png" : "jpg");
ImageIO.write(bimg, png ? "png" : "jpg", new File(outDir, name));
}
}
} finally {
doc.Close();
}
return 0;
}
public static void main(String[] args) throws IOException {
if (!Global.Init("YOUR-LICENSE-KEY")) {
System.err.println("License not activated");
}
System.out.println(convert(args[0], "", new File(args[1]), 1200, true, false));
}
}
A few notes on this code:
Global.Init(String serial)loads the native library and activates the license. On Linux it reads the CMaps and fonts from/root/res/by default, so adjust those paths inGlobal.javafor your deployment.back_clris the page background color in ARGB format. The SDK demos pass-1(opaque white). The Server source documents it only as “the background color”, so a zero-alpha value such as0x00000000should leave the background transparent: test it with your SDK version, and remember that transparency only survives if you save as PNG.- JPEG has no alpha channel, so the JPEG path renders into a
TYPE_INT_RGBimage. - If you prefer raw pixels,
RenderToBuf(int[] data, int w, int h, int back_clr, Matrix mat)fills an array of0xAARRGGBBvalues.
Server side: C#
The C# wrappers (RDDLib.comm, RDDLib.pdf) render into an RDDIB buffer, which can encode itself with SavePNG(path) or SaveJPG(path, quality):
using System;
using RDDLib.comm;
using RDDLib.pdf;
public static class PdfToImages
{
public static int Convert(string pdfPath, string outDir, float scale)
{
PDFDoc doc = new PDFDoc();
int err = doc.Open(pdfPath, "");
if (err != 0) return err;
int count = doc.GetPageCount();
for (int i = 0; i < count; i++)
{
PDFPage page = doc.GetPage(i);
if (page == null) break;
float pw = doc.GetPageWidth(i);
float ph = doc.GetPageHeight(i);
RDDIB dib = new RDDIB((int)(pw * scale), (int)(ph * scale));
RDMatrix mat = new RDMatrix(scale, -scale, 0, ph * scale);
page.RenderPrepare(dib);
if (page.Render(dib, mat, 2))
dib.SaveJPG(System.IO.Path.Combine(outDir, $"page_{i:D4}.jpg"), 90);
page.Close();
}
doc.Close();
return 0;
}
}
Call RDGlobal.Init() and RDGlobal.Active(key) (which returns 3 on success) once before converting, as the Windows demo does.
Android (Master)
On Android, the Master library renders into an android.graphics.Bitmap with Page.RenderToBmp(Bitmap, Matrix). The knowledge base article on converting PDFs to images notes that the logic is the same as on the server. Here it is with the current Master API, where Matrix lives in com.radaee.comm:
import android.content.Context;
import android.graphics.Bitmap;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import com.radaee.comm.Global;
import com.radaee.comm.Matrix;
import com.radaee.pdf.Document;
import com.radaee.pdf.Page;
public final class PdfToImages {
public static int convert(Context ctx, String pdfPath, String password,
File outDir, int size, boolean transparent) {
Global.Init(ctx); // license key is read from Global.mKey
Document doc = new Document();
int result = doc.Open(pdfPath, password);
if (result != 0) return result;
outDir.mkdirs();
int count = doc.GetPageCount();
for (int i = 0; i < count; i++) {
Page page = doc.GetPage(i);
if (page == null) continue;
float pw = doc.GetPageWidth(i);
float ph = doc.GetPageHeight(i);
float ratio = (size > 0) ? size / Math.max(pw, ph) : 1.0f;
Bitmap bmp = Bitmap.createBitmap((int) (pw * ratio), (int) (ph * ratio),
Bitmap.Config.ARGB_8888);
if (transparent) {
bmp.eraseColor(0x00000000); // fully transparent
page.RenderPrepare((Bitmap) null); // reset page status, no erase
} else {
page.RenderPrepare(bmp); // erases the bitmap to white
}
Matrix mat = new Matrix(ratio, -ratio, 0, ph * ratio);
boolean ok = page.RenderToBmp(bmp, mat);
mat.Destroy();
page.Close();
if (ok) {
File out = new File(outDir, "page_" + i + (transparent ? ".png" : ".jpg"));
try (FileOutputStream fos = new FileOutputStream(out)) {
bmp.compress(transparent ? Bitmap.CompressFormat.PNG
: Bitmap.CompressFormat.JPEG, 90, fos);
} catch (IOException e) {
e.printStackTrace();
}
}
bmp.recycle();
}
doc.Close();
return 0;
}
}
Transparent backgrounds on Android
Transparent backgrounds are among the most-read rendering topics in the knowledge base. The approach above follows the Android article: erase the bitmap to 0x00000000 and render without RenderPrepare(bmp), because that overload erases the bitmap to white. Older articles also call BMP.MulAlpha() afterwards. In the current Master source that method is marked deprecated since 3.12beta2, because the improved color blending no longer needs it.
Form fields are drawn with a translucent highlight (default 0x200040FF). The knowledge base converter turns it off before exporting. In Master for Android, call Global.setAnnotTransparency(0) after Global.Init.
iOS (Master)
The iOS Master library exposes Objective-C classes in PDFObjc.h: RDPDFDoc, RDPDFPage, RDPDFDIB and RDPDFMatrix. Initialize once with [RDVGlobal Init], which activates the serial set in RDVGlobal.m. Then render into a DIB and wrap its pixels in a CGImage, using the same bitmap flags as the sample app’s file browser:
#import <UIKit/UIKit.h>
#import "PDFObjc.h"
// Renders every page to PNG. Returns 0 or the open error code.
static int PDFPagesToPNG(NSString *path, NSString *password, NSString *outDir, float scale)
{
RDPDFDoc *doc = [[RDPDFDoc alloc] init];
int err = [doc open:path :password];
if (err != 0) return err;
[[NSFileManager defaultManager] createDirectoryAtPath:outDir
withIntermediateDirectories:YES attributes:nil error:nil];
int count = [doc pageCount];
for (int i = 0; i < count; i++) {
@autoreleasepool {
float pw = [doc pageWidth:i];
float ph = [doc pageHeight:i];
int iw = (int)(pw * scale);
int ih = (int)(ph * scale);
RDPDFPage *page = [doc page:i];
if (page == nil) continue;
RDPDFDIB *dib = [[RDPDFDIB alloc] init:iw :ih];
RDPDFMatrix *mat = [[RDPDFMatrix alloc] init:scale :-scale :0 :ph * scale];
[page renderPrepare:dib]; // erases the DIB to white
if (![page render:dib :mat :2]) continue;
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, [dib data], iw * ih * 4, NULL);
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
CGImageRef img = CGImageCreate(iw, ih, 8, 32, iw << 2, cs,
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
provider, NULL, false, kCGRenderingIntentDefault);
CGColorSpaceRelease(cs);
CGDataProviderRelease(provider);
NSData *png = UIImagePNGRepresentation([UIImage imageWithCGImage:img]);
CGImageRelease(img);
NSString *file = [outDir stringByAppendingPathComponent:
[NSString stringWithFormat:@"page_%04d.png", i]];
[png writeToFile:file atomically:YES];
}
}
return 0; // ARC releases the page, DIB and document objects
}
The @autoreleasepool block frees each page’s image before the next page is rendered, which matters for long documents.
Keeping memory under control
- Cap the image size. Pixel memory grows with the square of the scale. A 4096-pixel limit, as in the JSP demo, or a fixed longest side keeps memory use predictable.
- Release native objects promptly. Call
Matrix.Destroy()andPage.Close()after every page andDocument.Close()at the end. On Android,recycle()each bitmap after it has been saved. - Use embedded thumbnails when they exist.
Page.RenderThumb(Bitmap)on Android returnstrueonly if the page carries a thumbnail image, so fall back to a normal render when it returnsfalse. - Only need the first page? The Android sample’s grid view calls
Document.SetOpenFlag(3)before opening andGetPage0()to fetch the first page fast. The flag is global and makes the SDK assume every page has the size of the first one, so the sample restoresSetOpenFlag(1)right after opening.
Common pitfalls
- Upside-down output: the y scale must be negative, with
pageHeight * scaleas the y offset. - Black or missing background in JPEG files: JPEG cannot store alpha, so render on white or keep transparent output in PNG.
- Only a few pages rendered: without an activated license,
GetPagereturnsnullafter the first pages. Check the result of the init call. - Wrong fonts on Linux servers: make sure the resource paths in
Global.Init(Java) orRDGlobal.Init(C#) point to the folder that holdscmaps.dat,umaps.datand the font files.
Frequently asked questions
How do I convert a PDF page to PNG on a server?
Run the rdpage tool with the -exp option and a dpi value, or render the page in Java with Page.RenderToBuf into a BufferedImage and save it with ImageIO.
Which resolution should I use when converting PDF to image?
Page sizes are in points, so the scale is the target dpi divided by 72. A scale between 1.5 and 2.0 suits on-screen previews, while OCR or print-quality archives need about 300 dpi.
Can I render a page with a transparent background?
Yes on Android: erase the bitmap to fully transparent, render without RenderPrepare and save as PNG. On the server, pass a background color with zero alpha and test the result with your SDK version.
Related on radaeepdf.com
- RadaeePDF SDK for Server
- RadaeePDF SDK for Android
- Build a server-side PDF processing pipeline
- Download the free trial
Where to go next
- Server SDK CLI reference: rdpage -out and -exp
- Server Java Page.java (RenderToBuf)
- Server Java Matrix.java
- Server JSP demo: render pages to PNG
- Server Java rendering guide
- Server C# RDDCom.cs (RDDIB, RDMatrix, RDGlobal) and RDDPDF.cs
- Android Master Page.java, BMP.java and Global.java
- Android Master PDFGridItem.java (first-page thumbnails)
- iOS Master PDFObjc.h and RDFileCollectionViewController.m
- Knowledge base: Convert PDF to images and bitmaps (Server and Android)
- Knowledge base: Convert PDF to images and bitmaps (iOS)
- Knowledge base: Render bitmap with transparent background (Android)
- Knowledge base: How to create a thumbnail from a page of a PDF file
- Knowledge base: PDF linearization management