9

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 about iText, PDFBox and various other java pdf libraries, I am hoping for a pointer to some working example, or some how-to.

Thanks.

dasp
  • 909
  • 4
  • 13
  • 21

6 Answers6

18

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();
                }
            }
        });
    }
}
Community
  • 1
  • 1
jedierikb
  • 12,752
  • 22
  • 95
  • 166
  • the hasAlpha method missed can be found here http://www.biddata.net/joel/photo/final/Photo.java – zaletniy Aug 10 '10 at 13:43
  • @jedierikb I edited the link to pdf-renderer as it was no longer working, but I could not find a page with the examples. Maybe you know where it moved to. – Jacob Schoen Aug 13 '12 at 20:02
  • 1
    Neither link to exampledepot is working. Do you have any references to what library the examples used, or any other info that might help? – Tango Dec 20 '12 at 03:16
4

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

mark stephens
  • 3,205
  • 16
  • 19
1

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...

alaris
  • 21
  • 1
0

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.

Neeraj
  • 1,612
  • 7
  • 29
  • 47
-1

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)

Nikita Jain
  • 669
  • 8
  • 11
-2

Just start your for loop from 1 instead of 0. Your problem will be solved.

Ravi Amlani
  • 92
  • 1
  • 9