zoukankan      html  css  js  c++  java
  • 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");
    作者:郑金圣
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    HDU1205 吃糖果【水题】
    HDU2568 前进【水题】
    架构图初体验
    五层架构
    文件系统权限设计涉及范畴
    微服务
    领域驱动设计
    容器技术Docker
    架构总结
    仓储模式的简单理解
  • 原文地址:https://www.cnblogs.com/zhengjinsheng/p/11114621.html
Copyright © 2011-2022 走看看