解决的问题

有些时候我们需要在项目中展示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();
}
} }

Java中PDF的转换(图片)与展示的更多相关文章

  1. java中汉字自动转换成拼音

    java中汉字自动转换成拼音 1.需要下载jar包 pinyin4j.2.5.0.jar ,加入到WEB-INF下的lib里边,右键add to bulid path. 2.[代码]PinYinUti ...

  2. java中调用kettle转换文件

    java中调用kettle转换文件 通过命令行也能够调用,然后java中调用命令行代码也能够.这样没有和java代码逻辑无缝集成.本文说明kettle5.1中假设通过其它API和java代码无缝集成: ...

  3. java中的时区转换

    目录 java中的时区转换 一.时区的说明 二.时间的表示 三.时间戳 四.Date类和时间戳 五.java中的时区转换 java中的时区转换 一.时区的说明 地球表面按经线从东到西,被划成一个个区域 ...

  4. JAVA中pdf转图片的方法

    JAVA中实现pdf转图片可以通过第三方提供的架包,这里介绍几种常用的,可以根据自身需求选择使用. 一.icepdf.有收费版和开源版,几种方法里最推荐的.转换的效果比较好,能识别我手头文件中的中文, ...

  5. java读取pdf文本转换html

    补充:一下代码基于maven,现将依赖的jar包单独导出 地址:pdf jar 完整代码地址 也就两个文件 java读取pdf中的纯文字,这里使用的是pdfbox工具包 maven引入如下配置 < ...

  6. Java 设置PDF平铺图片背景(水印)

    一.概述及环境准备 本文介绍使用免费版PDF库-Free Spire.PDF for Java加载图片来设置成PDF平铺图片背景的效果,也可以作为平铺图片水印来使用:编辑代码前,需要先导入jar文件, ...

  7. 填坑:Java 中的日期转换

    我们之前讨论过时间,在Java 中有一些方法会出现横线?比如Date 过期方法. 参考文章:知识点:java一些方法会有横线?以Date 过期方法为例 Java中的日期和时间处理方法 Date类(官方 ...

  8. Java中数据类型默认转换和强制类型转换

    默认转换: a:由低到高一次为:(byte   short    char  )---int ---long ---float --- double b:注意:byte   short    char ...

  9. 【图片识别】Java中使用tess4J进行图片文字识别(支持中文)(转)

    http://blog.csdn.net/wsk1103/article/details/54173282 java中识别文字比较简单,使用的软件是tesseractocr(使用的版本是3.02,3以 ...

  10. JAVA中时间格式转换

    1.将任意日期格式的字符串转换为指定格式的字符串 //默认格式 String s1 = "20190110133236"; //给定格式 String s2 = "201 ...

随机推荐

  1. 【云原生】拿下 Gartner 容器产品第一,阿里云打赢云原生关键一战!

    近日,Gartner 发布 2020 年公共云容器报告,据报告显示,阿里云和 AWS 拥有最丰富的产品布局,覆盖 9 项产品能力,并列排名第一. 据 Gartner 分析师评论,阿里云拥有丰富的容器产 ...

  2. 深度解读 MongoDB 最全面的增强版本 4.4 新特性

    MongoDB 在今年正式发布了新的 4.4 大版本,这次的发布包含众多的增强 Feature,可以称之为是一个维护性的版本,而且是一个用户期待已久的维护性版本,MongoDB 官方也把这次发布称为「 ...

  3. 从no-code到low-code:企业级hpaPaaS的未来

    简介: 本文将简单谈一谈基于 no-code > low-code > pro-code 渐进式思路的研发体系. 引子 宜搭负责人骁勇给我举过一个例子,我们小时候逢年过节穿的衣服,都是去裁 ...

  4. WPF 解决 ObservableCollection 提示 Cannot change ObservableCollection during a CollectionChanged event 异常

    本文告诉大家在使用 ObservableCollection 时,抛出 InvalidOperationException 异常,提示 Cannot change ObservableCollecti ...

  5. WPF 如何获取有哪些 VisualBrush 用了某个控件

    我写了一个特殊的控件,我期望了解到有哪些 VisualBrush 捕获了此控件,或者说有哪些 VisualBrush 用了此控件的界面 本文的方法需要用到反射,需要使用 WPF 框架里面没有公开的字段 ...

  6. Prometheus+Grafana+alertmanager构建企业级监控系统(一)

    一.环境准备 k8s集群角色 IP 主机名 配置 控制节点 192.168.199.131 master centos7.9 4核6G 工作节点 192.168.199.128 monitor cen ...

  7. CMDB开发(三)

    6.API验证 # 加密复习 #1.简单的对称加密,token是固定的 客户端请求: import requests # 1.自定义token值 token = 'cxiong_token' # to ...

  8. 如何在M1 MACBOOK上准备好ORB-SLAM2的环境

    1. 环境 M1 Macbook Air Parallels Desktop 17 关于虚拟机,在之前尝试了UTM,但是性能欠佳,卡顿情况比较多,而且未能解决联网问题,最终只能含泪放弃 Paralle ...

  9. NOIP2023游寄

    Day -?? 模拟赛挂分. Day -18 模拟赛挂大分,挂分大于得分.(180/400,得分/标准分,下同) 连着挂了好多场了,感觉有点迷茫了. Day -17 模拟赛--AK了?(400/400 ...

  10. Ubuntu更新源文件报错:E: 仓库 “http://ppa.launchpad.net/chris-lea/node.js/ubuntu bionic Release” 没有 Release 文件。

    E: 仓库 "http://ppa.launchpad.net/chris-lea/node.js/ubuntu bionic Release" 没有 Release 文件. 一条 ...