我有一个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"));
当我使用代码时,图像文件提供完全错误的输出(out.png附加)
如何让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 );
相同的结果
答案 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:强>
答案 1 :(得分:3)
我使用PDFBox版本1.8.4获得与OP相同的结果。但在版本2.0.0-SNAPSHOT中,它看起来更好:
这里只有一些箭头更薄,一些箭头部分被错误地绘制成方框。
因此,
如何让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();
}
它工作正常。