将PDF转换为图像(具有适当的格式)

时间:2014-03-11 17:56:12

标签: android image pdf format pdfbox

我有一个pdf文件(附件)。 我的目标是使用pdfbox将pdf转换为图像(与在Windows中使用剪切工具相同)。 pdf有各种形状和文字。

我正在使用以下代码:

PDDocument doc = PDDocument.load("Hello World.pdf");
PDPage firstPage = (PDPage) doc.getDocumentCatalog().getAllPages().get(67);
BufferedImage bufferedImage = firstPage.convertToImage(imageType,screenResolution);
ImageIO.write(bufferedImage, "png",new File("out.png"));

This is the PDF i want to convert

当我使用代码时,图像文件提供完全错误的输出(out.png附加) This is the image file converted from pdfbox

如何让pdfbox像直接快照图像一样?

另外,我注意到png的图像质量不太好,有没有办法提高生成图像的分辨率?

编辑: 这是pdf(参见第68页) https://drive.google.com/file/d/0B0ZiP71EQHz2NVZUcElvbFNreEU/edit?usp=sharing

编辑2: 似乎所有的文字都很有意思。 我也尝试使用PDFImageWriter类

test.writeImage(doc, "png", null, 68, 69, "final.png",TYPE_USHORT_GRAY,200 );

相同的结果

3 个答案:

答案 0 :(得分:4)

使用PDFRenderer可以将PDF页面转换为图像格式。

使用PDF渲染器在Java中将PDF页面转换为图像。需要的罐子PDFRenderer-0.9.0

package com.pdfrenderer.examples;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import javax.imageio.ImageIO;

import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;

public class PdfToImage {
    public static void main(String[] args) {
        try {
            String sourceDir = "C:/Documents/Chemistry.pdf";// PDF file must be placed in DataGet folder
            String destinationDir = "C:/Documents/Converted/";//Converted PDF page saved in this folder

        File sourceFile = new File(sourceDir);
        File destinationFile = new File(destinationDir);

        String fileName = sourceFile.getName().replace(".pdf", "_cover");

        if (sourceFile.exists()) {
            if (!destinationFile.exists()) {
                destinationFile.mkdir();
                System.out.println("Folder created in: "+ destinationFile.getCanonicalPath());
            }

            RandomAccessFile raf = new RandomAccessFile(sourceFile, "r");
            FileChannel channel = raf.getChannel();
            ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
            PDFFile pdf = new PDFFile(buf);
            int pageNumber = 62;// which PDF page to be convert
            PDFPage page = pdf.getPage(pageNumber);

            System.out.println("Total pages:"+ pdf.getNumPages());

            // create the image
            Rectangle rect = new Rectangle(0, 0, (int) page.getBBox().getWidth(), (int) page.getBBox().getHeight());
            BufferedImage bufferedImage = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_RGB);

            // width & height, // clip rect, // null for the ImageObserver, // fill background with white, // block until drawing is done
            Image image = page.getImage(rect.width, rect.height, rect, null, true, true );
            Graphics2D bufImageGraphics = bufferedImage.createGraphics();
            bufImageGraphics.drawImage(image, 0, 0, null);

            File imageFile = new File( destinationDir + fileName +"_"+ pageNumber +".png" );// change file format here. Ex: .png, .jpg, .jpeg, .gif, .bmp

            ImageIO.write(bufferedImage, "png", imageFile);

            System.out.println(imageFile.getName() +" File created in: "+ destinationFile.getCanonicalPath());
        } else {
            System.err.println(sourceFile.getName() +" File not exists");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

<强> ConvertedImage:

Chemistry_cover_62

答案 1 :(得分:3)

我使用PDFBox版本1.8.4获得与OP相同的结果。但在版本2.0.0-SNAPSHOT中,它看起来更好:

enter image description here

这里只有一些箭头更薄,一些箭头部分被错误地绘制成方框。

因此,

  

如何让pdfbox像直接快照图像一样?

当将PDF渲染为图像时,当前版本(最高1.8.4)似乎有更大的缺陷。您可以切换到当前的开发版本(例如当前的主干,2.0.0-SNAPSHOT)或等到改进发布。

此外,一些小的赤字甚至在2.0.0-SNAPSHOT中。您可能希望将示例文档呈现给PDFBox人员(即在他们的JIRA中创建相应的问题),以便他们进一步改进PDFBox以满足您的需求。

  

另外,我注意到png的图像质量不太好,有没有办法提高生成图像的分辨率?

convertToImage参数有resolution次重载。您当前的代码将分辨率设置为screenResolution。提高此分辨率值。

PS:将PDF页面呈现为图像的代码已在2.0.0-SNAPSHOT中重构。而不是

BufferedImage image =  page.convertToImage();

你现在做

BufferedImage image =  RenderUtil.convertToImage(page);

我认为这样做是为了从核心类中删除直接AWT引用,因为AWT不可用于例如机器人。


PS :我在去年的答案中使用的SNAPSHOT只是一个快照,可能会有变化。 2.0.0版本仍处于开发阶段,很多事情都发生了变化。特别是没有RenderUtil级别了。相反,目前必须使用PDFRenderer包中的org.apache.pdfbox.rendering ...

答案 2 :(得分:2)

事实证明,jpedal(lgpl)完美地完成了转换(就像快照一样)。

这是我用过的:

PdfDecoder decode_pdf = new PdfDecoder(true);


FontMappings.setFontReplacements();

    decode_pdf.openPdfFile("Hello World.pdf"); 


 decode_pdf.setExtractionMode(0,800,3);

 try {

     for(int i=0;i<40;i++)
     {  
         BufferedImage img=decode_pdf.getPageAsImage(2+i);

    ImageIO.write(img, "png",new File(String.valueOf(i)+"out.png"));
     }
} catch (IOException ex) {
    Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}

    decode_pdf.closePdfFile();

} catch (PdfException e) {
    e.printStackTrace();
}

它工作正常。