2009-02-15 50 views
8

Necesito exportar las páginas de un documento PDF arbitrario a una serie de imágenes individuales en formato jpeg/png/etc. Necesito hacer esto en Java.Exportar páginas PDF a una serie de imágenes en Java

Aunque sé de iText, PDFBox y varias otras bibliotecas de java pdf, estoy esperando un puntero a algún ejemplo de trabajo, o algo de cómo hacerlo.

Gracias.

Respuesta

18

Aquí hay una manera de hacerlo, combinando algunos fragmentos de código de toda la web.

¿Cómo se dibuja un PDF en una imagen?

https://pdf-renderer.dev.java.net/examples.html

Creación de una imagen con búfer de una imagen

ORIGINAL: http://www.exampledepot.com/egs/java.awt.image/Image2Buf.html

ACTUALIZADO: How to convert buffered image to image and vice-versa?

Guardar un gráfico generado a un PNG o JPEG

ORIGINAL: http://www.exampledepot.com/egs/javax.imageio/Graphic2File.html

ACTUALIZADO: http://docs.oracle.com/javase/tutorial/2d/images/saveimage.html

combinado juntos en algo que funcione como este para convertir todas las páginas en imágenes:

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(); 
       } 
      } 
     }); 
    } 
} 
+0

Esto es exactamente lo que estaba buscando, ¡gracias! – dasp

+0

el método hasAlpha perdido se puede encontrar aquí http://www.biddata.net/joel/photo/final/Photo.java – zaletniy

+0

@jedierikb He editado el enlace al pdf-renderer porque ya no funcionaba, pero pude no encuentras una página con los ejemplos. Quizás sabes a dónde se mudó. –

-1

Simplemente inicie su bucle for desde 1 en lugar de 0. Su problema será resuelto.

1

Si descubre que el renderizador solar no funciona con todos sus documentos PDF, puede buscar el uso de jPDFImages.

Para ser más eficiente, debe convertir cada página PDF a una imagen almacenada en el búfer y desde allí convertir a los diversos formatos de imagen que necesita. Esto evitaría tener que convertir de PDF a imágenes para cada formato.

Aquí está el enlace para convertir de PDF a imágenes en buffer usando jPDFImages: http://kbdeveloper.qoppa.com/jpdfimages/codesampleconvertpdfpageintobufferedimageinjava

Para cada imagen de la página simplemente puede exportar a diferentes formatos de imagen: ImageIO.write (pageBufferedImage, "JPEG", OutputFile) ; ImageIO.write (pageBufferedImage, "PNG", outputFile); etc ...

0

Existen diferentes bibliotecas para hacerlo. Lo he logrado con PDFBox. Pero en mi opinión, la solución más eficiente es usar ghostscript. Pero si cree que necesita una solución fácil, use ImageMagick. Pero ImageMagick llama internamente al ghostscript. Usar ghostscript o imagemagick te da una mejor solución. Es mucho más rápido que cualquier otra biblioteca.

Cuestiones relacionadas