之前项目里面有用到显示pdf的模块,需要将pdf显示处理,也结合了一些插件,pdf.js是firefox浏览器推出的一套h5渲染pdf的前端插件,支持移动端pc端,但是显示效果不太好,有时候需要嵌套到移动的webview里面,显示时候会有问题,pc端,由于直接采用iframe就支持,但是个别浏览器还是不支持,所以为了一次性解决兼容,把所有的pdf转换成图片就行,这样就不会出现兼容问题了
但是在实际操作时,发现还是有点问题,有的pdf中字体较多,linux服务器上字体库没有时,当时采用的时icetext的类库,发现当pdf字体icetext无法识别时就会出现乱码,而且生成图片时,是按照pdf一页一张图片生成的,显示不太友好.
最终发现Apache的,pdfbox支持转出的图片效果比较好,而且也不会乱码,但是pdf对应多个图片
需求2解决了,如何解决一个pdf文件对应一张图片的问题尼?
要是能在内存中把多张图片合并成一张图片就行了,那么怎么才能合并图片尼?
这个其实也不难,之前上学的时候,书本上曾经说个,图片文件就是一个一个的像素点组成的,只能我们能获取并保存每张图片的所有像素点,就可以随时还原这张图片,当然为了保证图片不失真,还需要保存原始宽高.
代码中采用的时最新的pdfbox2.0版本,大家可以去官网自行下载
package com.taoyuanx.utils;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
public class PdfToImage {
public static void main(String[] args) {
pdfToImage("d://test.pdf");
}
//经过测试,dpi为96,100,105,120,150,200中,105显示效果较为清晰,体积稳定,dpi越高图片体积越大
//一般电脑显示分辨率为96
public static final float DEFAULT_DPI=105;
/**pdf转图片
* @param pdfPath
*/
public static void pdfToImage(String pdfPath){
try{
if(pdfPath==null||"".equals(pdfPath)||!pdfPath.endsWith(".pdf"))
return;
//图像合并使用参数
int width = 0; // 总宽度
int[] singleImgRGB; // 保存一张图片中的RGB数据
int shiftHeight = 0;
BufferedImage imageResult = null;//保存每张图片的像素值
//利用PdfBox生成图像
PDDocument pdDocument = PDDocument.load(new File(pdfPath));
PDFRenderer renderer = new PDFRenderer(pdDocument);
//循环每个页码
for(int i=0,len=pdDocument.getNumberOfPages(); iint imageHeight=image.getHeight();
int imageWidth=image.getWidth();
if(i==0){//计算高度和偏移量
width=imageWidth;//使用第一张图片宽度;
//保存每页图片的像素值
imageResult= new BufferedImage(width, imageHeight*len, BufferedImage.TYPE_INT_RGB);
}else{
shiftHeight += imageHeight; // 计算偏移高度
}
singleImgRGB= image.getRGB(0, 0, width, imageHeight, null, 0, width);
imageResult.setRGB(0, shiftHeight, width, imageHeight, singleImgRGB, 0, width); // 写入流中
}
pdDocument.close();
File outFile = new File(pdfPath.replace(".pdf", "_"+DEFAULT_DPI+".jpg"));
ImageIO.write(imageResult, "jpg", outFile);// 写图片
}catch (Exception e) {
e.printStackTrace();
}
}
}
这里只写了pdf转图片的代码,其实pdfbox还有很多操作,比如水印,绘图之类,如果我们想对生成的图片做些裁剪,绘制文字之类,可以是bufferimage这个java自带的类实现,可能图片会有些失真.
因为可能业务后续还涉及到对图片的操作,所以就了解了下,图片类库,发现阿里巴巴的simpleimage比较好用,图片的裁剪,翻转也不会失真,但是就是有些bug,使用simpleimage时发现,绘制自定义字体时,必须使用全量参数类实例化DrawTextItem 的子类.
simpleimage还依赖了oracle的jai图片类库,大家使用时可能还需要去挂网下载,简单的操作图片还可以的.