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();
}
}
}
Java中PDF的转换(图片)与展示的更多相关文章
- java中汉字自动转换成拼音
java中汉字自动转换成拼音 1.需要下载jar包 pinyin4j.2.5.0.jar ,加入到WEB-INF下的lib里边,右键add to bulid path. 2.[代码]PinYinUti ...
- java中调用kettle转换文件
java中调用kettle转换文件 通过命令行也能够调用,然后java中调用命令行代码也能够.这样没有和java代码逻辑无缝集成.本文说明kettle5.1中假设通过其它API和java代码无缝集成: ...
- java中的时区转换
目录 java中的时区转换 一.时区的说明 二.时间的表示 三.时间戳 四.Date类和时间戳 五.java中的时区转换 java中的时区转换 一.时区的说明 地球表面按经线从东到西,被划成一个个区域 ...
- JAVA中pdf转图片的方法
JAVA中实现pdf转图片可以通过第三方提供的架包,这里介绍几种常用的,可以根据自身需求选择使用. 一.icepdf.有收费版和开源版,几种方法里最推荐的.转换的效果比较好,能识别我手头文件中的中文, ...
- java读取pdf文本转换html
补充:一下代码基于maven,现将依赖的jar包单独导出 地址:pdf jar 完整代码地址 也就两个文件 java读取pdf中的纯文字,这里使用的是pdfbox工具包 maven引入如下配置 < ...
- Java 设置PDF平铺图片背景(水印)
一.概述及环境准备 本文介绍使用免费版PDF库-Free Spire.PDF for Java加载图片来设置成PDF平铺图片背景的效果,也可以作为平铺图片水印来使用:编辑代码前,需要先导入jar文件, ...
- 填坑:Java 中的日期转换
我们之前讨论过时间,在Java 中有一些方法会出现横线?比如Date 过期方法. 参考文章:知识点:java一些方法会有横线?以Date 过期方法为例 Java中的日期和时间处理方法 Date类(官方 ...
- Java中数据类型默认转换和强制类型转换
默认转换: a:由低到高一次为:(byte short char )---int ---long ---float --- double b:注意:byte short char ...
- 【图片识别】Java中使用tess4J进行图片文字识别(支持中文)(转)
http://blog.csdn.net/wsk1103/article/details/54173282 java中识别文字比较简单,使用的软件是tesseractocr(使用的版本是3.02,3以 ...
- JAVA中时间格式转换
1.将任意日期格式的字符串转换为指定格式的字符串 //默认格式 String s1 = "20190110133236"; //给定格式 String s2 = "201 ...
随机推荐
- 【云原生】拿下 Gartner 容器产品第一,阿里云打赢云原生关键一战!
近日,Gartner 发布 2020 年公共云容器报告,据报告显示,阿里云和 AWS 拥有最丰富的产品布局,覆盖 9 项产品能力,并列排名第一. 据 Gartner 分析师评论,阿里云拥有丰富的容器产 ...
- 深度解读 MongoDB 最全面的增强版本 4.4 新特性
MongoDB 在今年正式发布了新的 4.4 大版本,这次的发布包含众多的增强 Feature,可以称之为是一个维护性的版本,而且是一个用户期待已久的维护性版本,MongoDB 官方也把这次发布称为「 ...
- 从no-code到low-code:企业级hpaPaaS的未来
简介: 本文将简单谈一谈基于 no-code > low-code > pro-code 渐进式思路的研发体系. 引子 宜搭负责人骁勇给我举过一个例子,我们小时候逢年过节穿的衣服,都是去裁 ...
- WPF 解决 ObservableCollection 提示 Cannot change ObservableCollection during a CollectionChanged event 异常
本文告诉大家在使用 ObservableCollection 时,抛出 InvalidOperationException 异常,提示 Cannot change ObservableCollecti ...
- WPF 如何获取有哪些 VisualBrush 用了某个控件
我写了一个特殊的控件,我期望了解到有哪些 VisualBrush 捕获了此控件,或者说有哪些 VisualBrush 用了此控件的界面 本文的方法需要用到反射,需要使用 WPF 框架里面没有公开的字段 ...
- Prometheus+Grafana+alertmanager构建企业级监控系统(一)
一.环境准备 k8s集群角色 IP 主机名 配置 控制节点 192.168.199.131 master centos7.9 4核6G 工作节点 192.168.199.128 monitor cen ...
- CMDB开发(三)
6.API验证 # 加密复习 #1.简单的对称加密,token是固定的 客户端请求: import requests # 1.自定义token值 token = 'cxiong_token' # to ...
- 如何在M1 MACBOOK上准备好ORB-SLAM2的环境
1. 环境 M1 Macbook Air Parallels Desktop 17 关于虚拟机,在之前尝试了UTM,但是性能欠佳,卡顿情况比较多,而且未能解决联网问题,最终只能含泪放弃 Paralle ...
- NOIP2023游寄
Day -?? 模拟赛挂分. Day -18 模拟赛挂大分,挂分大于得分.(180/400,得分/标准分,下同) 连着挂了好多场了,感觉有点迷茫了. Day -17 模拟赛--AK了?(400/400 ...
- 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 文件. 一条 ...