zoukankan      html  css  js  c++  java
  • Java中PDF的转换(图片)与展示

    解决的问题

    有些时候我们需要在项目中展示PDF,但是直接在浏览器中加入PDF展示的插件,存在兼容性问题,某些浏览器显示效果不理想,所以我们可以将PDF转为图片,然后已图片的方式展示,效果很好。

    那么怎么将PDF转为图片呢?有两种方式:

    产品 特点
    Apache 的 PDF box 免费;速度稍慢一点,但可以接受
    E-iceblue 的 Spire.PDF for Java 转换效果很好;速度快;功能强大,支持转多种格式;收费

    Spire.PDF for Java 的转换效果很好,但是如果不购买,转换过后会添加一些水印文字

    参考链接:https://www.cnblogs.com/Yesi/p/11233238.html

    PDF Box的使用

    <dependency>
    	<groupId>net.sf.cssbox</groupId>
    	<artifactId>pdf2dom</artifactId>
    	<version>1.7</version>
    </dependency>
    <dependency>
    	<groupId>org.apache.pdfbox</groupId>
    	<artifactId>pdfbox</artifactId>
    	<version>2.0.12</version>
    </dependency>
    <dependency>
    	<groupId>org.apache.pdfbox</groupId>
    	<artifactId>pdfbox-tools</artifactId>
    	<version>2.0.12</version>
    </dependency>
    

    多页PDF生成多张图片

    新建一个 PdfUtil 工具类

    public class PdfUtil {
    
        private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PdfUtil.class);
    
        /***
         * PDF文件转PNG图片,全部页数
         *
         * @param pdfFilePath pdf完整路径
         * @param dpi dpi越大转换后越清晰,相对转换速度越慢
         */
        public static void pdf2Image(String pdfFilePath, int dpi) {
            File file = new File(pdfFilePath);
            PDDocument pdDocument;
            try {
                String imgPdfPath = file.getParent();
                int dot = file.getName().lastIndexOf('.');
                // 获取图片文件名
                String imagePdfName = file.getName().substring(0, dot);
    
                pdDocument = PDDocument.load(file);
                PDFRenderer renderer = new PDFRenderer(pdDocument);
                /* dpi越大转换后越清晰,相对转换速度越慢 */
                PdfReader reader = new PdfReader(pdfFilePath);
                int pages = reader.getNumberOfPages();
                StringBuffer imgFilePath;
                for (int i = 0; i < pages; i++) {
                    String imgFilePathPrefix = imgPdfPath + File.separator + imagePdfName;
                    imgFilePath = new StringBuffer();
                    imgFilePath.append(imgFilePathPrefix);
                    imgFilePath.append("_");
                    imgFilePath.append((i + 1));
                    imgFilePath.append(".png");
                    File dstFile = new File(imgFilePath.toString());
                    BufferedImage image = renderer.renderImageWithDPI(i, dpi);
                    ImageIO.write(image, "png", dstFile);
                }
                log.info("PDF文档转PNG图片成功!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }
    

    多页PDF组合成一张图片

    public class PdfUtil {
    
        public static final int DEFAULT_DPI = 150;
    
        /**
         * pdf转图片
         * 多页PDF会每页转换为一张图片,下面会有多页组合成一页的方法
         *
         * @param pdfFile pdf文件路径
         * @param outPath 图片输出路径
         * @param dpi 相当于图片的分辨率,值越大越清晰,但是转换时间变长
         */
        public static void pdf2multiImage(String pdfFile, String outPath, int dpi) {
            if (ObjectUtil.isEmpty(dpi)) {
                // 如果没有设置DPI,默认设置为150
                dpi = DEFAULT_DPI;
            }
            try (PDDocument pdf = PDDocument.load(new FileInputStream(pdfFile))) {
                int actSize = pdf.getNumberOfPages();
                List<BufferedImage> picList = Lists.newArrayList();
                for (int i = 0; i < actSize; i++) {
                    BufferedImage image = new PDFRenderer(pdf).renderImageWithDPI(i, dpi, ImageType.RGB);
                    picList.add(image);
                }
                // 组合图片
                ImageUtil.yPic(picList, outPath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    新建 ImageUtil 类

    public class ImageUtil {
    
        private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ImageUtil.class);
    
        /**
         * 将宽度相同的图片,竖向追加在一起 ##注意:宽度必须相同
         *
         * @param picList 文件流数组
         * @param outPath 输出路径
         */
        public static void yPic(List<BufferedImage> picList, String outPath) {// 纵向处理图片
            if (picList == null || picList.size() <= 0) {
                log.info("图片数组为空!");
                return;
            }
            try {
                // 总高度
                int height = 0,
                        // 总宽度
                        width = 0,
                        // 临时的高度 , 或保存偏移高度
                        offsetHeight = 0,
                        // 临时的高度,主要保存每个高度
                        tmpHeight = 0,
                        // 图片的数量
                        picNum = picList.size();
                // 保存每个文件的高度
                int[] heightArray = new int[picNum];
                // 保存图片流
                BufferedImage buffer = null;
                // 保存所有的图片的RGB
                List<int[]> imgRgb = new ArrayList<int[]>();
                // 保存一张图片中的RGB数据
                int[] tmpImgRgb;
                for (int i = 0; i < picNum; i++) {
                    buffer = picList.get(i);
                    // 图片高度
                    heightArray[i] = offsetHeight = buffer.getHeight();
                    if (i == 0) {
                        // 图片宽度
                        width = buffer.getWidth();
                    }
                    // 获取总高度
                    height += offsetHeight;
                    // 从图片中读取RGB
                    tmpImgRgb = new int[width * offsetHeight];
                    tmpImgRgb = buffer.getRGB(0, 0, width, offsetHeight, tmpImgRgb, 0, width);
                    imgRgb.add(tmpImgRgb);
                }
                // 设置偏移高度为0
                offsetHeight = 0;
                // 生成新图片
                BufferedImage imageResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                for (int i = 0; i < picNum; i++) {
                    tmpHeight = heightArray[i];
                    if (i != 0) {
                        // 计算偏移高度
                        offsetHeight += tmpHeight;
                    }
                    // 写入流中
                    imageResult.setRGB(0, offsetHeight, width, tmpHeight, imgRgb.get(i), 0, width);
                }
                File outFile = new File(outPath);
                // 写图片
                ImageIO.write(imageResult, "png", outFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
    }
    
  • 相关阅读:
    kernel list 实践
    rpm打包
    void out2() const{
    剑指offer python版 两个链表的第一个公共结点
    剑指offer python版 数组中的逆序对
    剑指offer python版 字符串中第一个只出现一次的字符
    剑指offer python版 丑数 (只含有2,3,5因子)
    剑指offer python版 最长不含重复字符的子字符
    剑指offer python版 礼物的最大价值
    剑指offer python版 数字序列中某一位的数字
  • 原文地址:https://www.cnblogs.com/reroyalup/p/13533882.html
Copyright © 2011-2022 走看看