I need to export the pages of an arbitrary PDF document into a series of individual images in jpeg/png/etc format. I need to do this in in Java.
Although I do know
PDF to Bitmap (Android compatible code)
File pdfFile = new File(filePath);
PdfRenderer renderer = new PdfRenderer(ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY));
final int pageCount = renderer.getPageCount();
//Currently for a page, iterate for all the pages
PdfRenderer.Page page = renderer.openPage(pageCount);
int width = page.getWidth();
int height = page.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Bitmap to PNG (or any other format)
Just start your for loop from 1 instead of 0. Your problem will be solved.
If you find out that the sun renderer is not working for all your PDF documents, you may look into using jPDFImages.
To be more efficient, you should convert each PDF page to a buffered image and from there convert to the various image formats you need. This would avoid having to convert from PDF to images for each format.
Here is the link to convert from PDF to buffered images using jPDFImages: http://kbdeveloper.qoppa.com/jpdfimages/codesampleconvertpdfpageintobufferedimageinjava
For each page image you can simply export to different image formats: ImageIO.write(pageBufferedImage, "JPEG", outputFile); ImageIO.write(pageBufferedImage, "PNG", outputFile); etc...
There are different libraries to do it. I have achieved this with PDFBox. But in my opinion the most efficient solution is to use ghostscript. But if you think you need an easy solution, use ImageMagick. But ImageMagick internally calls the ghostscript. Using ghostscript or imagemagick give you a better solution. It is much faster than any other libraries.
Here is one way to do it, combining some code fragments from around the web.
How do I draw a PDF into an Image?
https://pdf-renderer.dev.java.net/examples.html
Creating a Buffered Image from an Image
ORIGINAL: http://www.exampledepot.com/egs/java.awt.image/Image2Buf.html
UPDATED: How to convert buffered image to image and vice-versa?
Saving a Generated Graphic to a PNG or JPEG File
ORIGINAL: http://www.exampledepot.com/egs/javax.imageio/Graphic2File.html
UPDATED: http://docs.oracle.com/javase/tutorial/2d/images/saveimage.html
Combined together into something that works like this to turn all the pages into images:
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import javax.swing.*;
import javax.imageio.*;
import java.awt.image.*;
public class ImageMain {
public static void setup() throws IOException {
// load a pdf from a byte buffer
File file = new File("test.pdf");
RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
PDFFile pdffile = new PDFFile(buf);
int numPgs = pdffile.getNumPages();
for (int i = 0; i < numPgs; i++) {
// draw the first page to an image
PDFPage page = pdffile.getPage(i);
// get the width and height for the doc at the default zoom
Rectangle rect = new Rectangle(0, 0, (int) page.getBBox().getWidth(), (int) page.getBBox().getHeight());
// generate the image
Image img = page.getImage(rect.width, rect.height, // width & height
rect, // clip rect
null, // null for the ImageObserver
true, // fill background with white
true // block until drawing is done
);
// save it as a file
BufferedImage bImg = toBufferedImage(img);
File yourImageFile = new File("page_" + i + ".png");
ImageIO.write(bImg, "png", yourImageFile);
}
}
// This method returns a buffered image with the contents of an image
public static BufferedImage toBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage) image;
}
// This code ensures that all the pixels in the image are loaded
image = new ImageIcon(image).getImage();
// Determine if the image has transparent pixels; for this method's
// implementation, see e661 Determining If an Image Has Transparent
// Pixels
boolean hasAlpha = hasAlpha(image);
// Create a buffered image with a format that's compatible with the
// screen
BufferedImage bimage = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
try {
// Determine the type of transparency of the new buffered image
int transparency = Transparency.OPAQUE;
if (hasAlpha) {
transparency = Transparency.BITMASK;
}
// Create the buffered image
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency);
} catch (HeadlessException e) {
// The system does not have a screen
}
if (bimage == null) {
// Create a buffered image using the default color model
int type = BufferedImage.TYPE_INT_RGB;
if (hasAlpha) {
type = BufferedImage.TYPE_INT_ARGB;
}
bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
}
// Copy image to buffered image
Graphics g = bimage.createGraphics();
// Paint the image onto the buffered image
g.drawImage(image, 0, 0, null);
g.dispose();
return bimage;
}
public static boolean hasAlpha(Image image) {
// If buffered image, the color model is readily available
if (image instanceof BufferedImage) {
BufferedImage bimage = (BufferedImage) image;
return bimage.getColorModel().hasAlpha();
}
// Use a pixel grabber to retrieve the image's color model;
// grabbing a single pixel is usually sufficient
PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
try {
pg.grabPixels();
} catch (InterruptedException e) {
}
// Get the image's color model
ColorModel cm = pg.getColorModel();
return cm.hasAlpha();
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
ImageMain.setup();
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
}
If you consider the JPedal PDF library, its built in and documented with eample source at https://support.idrsolutions.com/hc/en-us/articles/115001978091-Convert-PDF-Files-to-Image