PDF转图片

 有人可能问,族长今天为什么要写有关“PDF生成图片”呢?

        我之所以写这篇文章,是因为最近的项目中有实际场景需要用到,因此将实现的过程分享大家,可能在你的以后的项目中也会用到,所谓前人种树后人乘凉嘛,希望我种的每棵“树”能为大家提供便利;

        言归正传,由于我们之前提供给用户下载的电子发票都是pdf格式,可是很多人在手机上下载电子发票后发现不能打开pdf格式的电子发票,这就给用户带来了很多不便,于是乎,我们就着手将pdf格式的发票转成图片格式便于查看;下面我们就一起去看看怎样去实现该功能;

        pdf转图片的类库有好几种,我今天就只说两种我实际用过的pdfbox和pdfrenderer,两种类库各有优势:

pdfbox->转换效率较低,图片DPI值容易控制,图片高清,pdf页数过多或者DPI设置过大容易内存溢出,但是内含字体较为全面,如果考虑到要求转换高清、文件小、内含特殊字体可选用该类库;
pdfrenderer->这个应该是我知道的所有转换效率最高的一个,可是包含字体较少,有些pdf是无法转换的,比如国内的那种发票就转不成图片,经过我实际测试大部分转换时没问题;

        看了上面两个类库的优缺点如果是你想做发票转换你会选哪个呢?

        相信聪明的你已经想到了我选用的是pdfbox,因为我们的一个订单最多不会超过5张发票,还需要高清展示,加上pdfrenderer貌似对中国那种电子发票内的字体识别的不是很好,生成出来就有一个税务部门的一个红印章,因此选择pdfbox是最好不过的;

        操作四部曲:

        第一步:下载并引入的相关jar包,需要用到jar文件分别是pdfbox-2.0.4.jar、fontbox-2.0.4.jar和commons-logging-1.2.jar;

        第二部:将pdf转成的所有图片加载到内存中,如下:

public static List<BufferedImage> convertToImage(byte[] file) throws IOException {
        PDDocument document = PDDocument.load(file);
        PDFRenderer pdfRenderer = new PDFRenderer(document);
        //存储pdf中每一页BufferedImage
        List<BufferedImage> bufferedImageList = new ArrayList<>();
        //遍历PDF文件中的所有页,每一个都会生成一个单独的图片
        for (int page = 0;page<document.getNumberOfPages();page++){
            BufferedImage img = pdfRenderer.renderImageWithDPI(page, 100, ImageType.RGB);//注意此处的参数100可以调整,值越大图片越清晰
            bufferedImageList.add(img);
        }
        document.close();
        return bufferedImageList;
    }

        第三部:下来我们就需要将所有内存中的图片拼接成一张图片,拼接方法如下:

public static BufferedImage concat(List<BufferedImage> images) throws IOException {
        int heightTotal = 0;
        for(int j = 0; j < images.size(); j++) {
            heightTotal += images.get(j).getHeight();
        }
        int heightCurr = 0;
        BufferedImage concatImage = new BufferedImage(images.get(0).getWidth(), heightTotal, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = concatImage.createGraphics();
        for(int j = 0; j < images.size(); j++) {
            g2d.drawImage(images.get(j), 0, heightCurr, null);
            heightCurr += images.get(j).getHeight();
        }
        g2d.dispose();
        return concatImage;
}

        第四部:将内存中拼接好的图片生成实际图片

public static void generalImage(BufferedImage image,String path) throws ImageFormatException, IOException {
        FileOutputStream out = new FileOutputStream(path);
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        encoder.encode(image);
        out.close();
    }

有了以上四部我们就可以进行测试了,将test.pdf转成test.jpg(因为手头没有多页发票pdf且随便找一个多页pdf进行测试)

List<BufferedImage> list = FileManagerSystem.convertToImage(IoCommonUtil.readInputStream(new FileInputStream(new File("F:/迅雷下载/test.pdf"))));
        FileManagerSystem.generalImage(FileManagerSystem.concat(list), "F:/迅雷下载/test.jpg");
作者:郑金圣
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/zhengjinsheng/p/11114621.html