网上找了很多PDF转JPG的方法。有纯java转的,有转换工具转换的,还有插件转换的,其中主要有:pdfbox、PDFRenderer、xpdf
转换后的效果基本都是分辨率低,有失真,或者有中文转换问题。
如果对于没有分辨率要求的话可以考虑一下PDFRenderer,基本就可以满足你的需求了。
pdfbox存在中文转换问题,当然网上也有一些解决方法,有兴趣也可以研究一下。
而对于转换工具来说,转换的效果自然是满意的,其中,有pdftoimage、PDFJPG.exe(推荐)下载地址:http://yunpan.cn/QpnVfxsZX493b ,但是如果程序要调用的话就不行了,因为只支持图形界面,不支持命令行调用。故而对于需要语言来调用的话就得另找了。
后来找了C#语言的, 这篇文章可谓是各式各样,不过都是用到C#的,如果用java呢?
我就想使用java来调用dll,进而实现PDF转JPG的方法。
再后来加了个群后,找到一个比较靠谱的(转换效果好,分辨率高)的,就是利用jacob调用adobe动态库来转换。
不过这个程序缺点除了该博文讲到的效率慢些,我觉得还有就是需要安装Acrobat这个限制。但转换效果还是挺不错的。源生态的。
我对该程序做了一下修改,主要就是增加一个缩放尺寸的,还有释放Acrobat.exe对PDF的操作。
package com.test.tool;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class Pdf2Jpg {
/**
*
* @param filepath
* pdf路径
* @param savePath
* img保存路径
* @param times
* 缩放比例 如:1f为原图比例
* @throws IOException
*/
public static void savaPageAsJpgByAcrobat(String filepath, String savePath,
float times) throws IOException {
ComThread.InitSTA();//初始化com的线程
// 输出
FileOutputStream out = null;
// PDF页数
int pageNum = 0;
// PDF宽、高
int x, y = 0;
// PDF控制对象
Dispatch pdfObject = null;
// PDF坐标对象
Dispatch pointxy = null;
// pdfActiveX PDDoc对象 主要建立PDF对象
ActiveXComponent app = new ActiveXComponent("AcroExch.PDDoc");
// pdfActiveX PDF的坐标对象
ActiveXComponent point = new ActiveXComponent("AcroExch.Point");
try {
// 得到控制对象
pdfObject = app.getObject();
// 得到坐标对象
pointxy = point.getObject();
// 打开PDF文件,建立PDF操作的开始
Dispatch.call(pdfObject, "Open", new Variant(filepath));
// 得到当前打开PDF文件的页数
pageNum = Dispatch.call(pdfObject, "GetNumPages").toInt();
for (int i = 0; i < pageNum; i++) {
// 根据页码得到单页PDF
Dispatch page = Dispatch.call(pdfObject, "AcquirePage",
new Variant(i)).toDispatch();
// 得到PDF单页大小的Point对象
Dispatch pagePoint = Dispatch.call(page, "GetSize")
.toDispatch();
// 创建PDF位置对象,为拷贝图片到剪贴板做准备
ActiveXComponent pdfRect = new ActiveXComponent("AcroExch.Rect");
// 得到单页PDF的宽
int imgWidth = (int) (Dispatch.get(pagePoint, "x").toInt() * 2 * times);
// 得到单页PDF的高
int imgHeight = (int) (Dispatch.get(pagePoint, "y").toInt() * 2 * times);
// 控制PDF位置对象
Dispatch pdfRectDoc = pdfRect.getObject();
// 设置PDF位置对象的值
Dispatch.put(pdfRectDoc, "Left", new Integer(0));
Dispatch.put(pdfRectDoc, "Right", new Integer(imgWidth));
Dispatch.put(pdfRectDoc, "Top", new Integer(0));
Dispatch.put(pdfRectDoc, "Bottom", new Integer(imgHeight));
// 将设置好位置的PDF拷贝到Windows剪切板,参数:位置对象,宽起点,高起点,分辨率
Dispatch.call(page, "CopyToClipboard", new Object[] {
pdfRectDoc, 0, 0, 200 * times });
Image image = getImageFromClipboard();
BufferedImage tag = new BufferedImage(imgWidth, imgHeight, 8);
Graphics graphics = tag.getGraphics();
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
// 输出图片
ImageIO.write(tag, "JPEG", new File(savePath + (i+1) + ".jpg"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭PDF
app.invoke("Close", new Variant[] {});
ComThread.Release();//关闭com的线程 真正kill进程
}
}
public static Image getImageFromClipboard() throws Exception {
Clipboard sysc = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable cc = sysc.getContents(null);
if (cc == null)
return null;
else if (cc.isDataFlavorSupported(DataFlavor.imageFlavor))
return (Image) cc.getTransferData(DataFlavor.imageFlavor);
return null;
}
/*public static void main(String[] args) throws IOException {
savaPageAsJpgByAcrobat("D:/test/pdf2html/uploadAndDownload/diyizu.pdf",
"D:/test/pdf2html/uploadAndDownload/img", 0.25f);
}*/
}
需要下载jacob-1.17-M2: http://yunpan.cn/QpnjIZK7D4jKC
同时还要安装Acrobate
在此也非常感谢该博友对我的提点。