前提,目前java处理pdf 转换图片,能达到高清的很少。所有的java pdf工具我都试过了
,或多或少都有一些问题,达不到理想的效果。
我试过pdfbox、PDFRenderer、xpdf、jpedal等等pdf工具,不是中文乱码、字体不识别、
格式混乱、就是分辨率过低,毕竟都是开源的工具。其中有一个收费的纯java的pdf工具转换效
果非常理想,就是太贵了。这里附上这个收费的地址,有兴趣的可以去看看,反正很贵就是了,
中国有代理销售商http://www.qoppa.com/。
最后就在网上漫无目的搜索,就发现了一个解决方案,是C#解决pdf转换图片的案例。很
感谢这位同仁给了我启发,他的文章地址是:http://blog.csdn.net/shi0090/article/details/7262199,
里面全是C#的pdf转换图片的案例。通过这位仁兄的调用adobe官方的dll接口得到启发,我就用jacob
(java调用dll的一个工具包),通过调用adobe官方提供的Acrobat.dll接口进行pdf转图片,效果不错
很清晰,pdf支持的字体均可以转换出来。
这个方法同时也有问题,就是不支持多线程同时调用。一旦出现并发的情况,会报错windows剪切板
不可用。目前我想到的方法是用多线程排队的机制进行转换,一定程度上效率不高。如果各位同学有
更好的解决方法,欢迎来讨论。
需要的包:
jacob-1.17-M2
adobe arcobat pro X
这种方法只适用于windows下,linux的同学就没办法了。
具体代码如下:
jacob调用dll转换的具体处理代码
public static void savaPageAsJpgByAcrobat(String filepath,String savePath){ //输出 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); //得到单页PDF的高 int imgHeight = (int) (Dispatch.get(pagePoint, "y").toInt() * 2); //控制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}); 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+".jpg")); } } catch (Exception e) { e.printStackTrace(); } finally { //关闭PDF app.invoke("Close", new Variant[] {}); } }
复制剪切板的内容代码:
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; }