java图片处理以及pdf转图片

来源:互联网 发布:java 线程池 等待队列 编辑:程序博客网 时间:2024/06/05 23:04

java图片处理以及pdf转图片

1.需求

之前项目里面有用到显示pdf的模块,需要将pdf显示处理,也结合了一些插件,pdf.js是firefox浏览器推出的一套h5渲染pdf的前端插件,支持移动端pc端,但是显示效果不太好,有时候需要嵌套到移动的webview里面,显示时候会有问题,pc端,由于直接采用iframe就支持,但是个别浏览器还是不支持,所以为了一次性解决兼容,把所有的pdf转换成图片就行,这样就不会出现兼容问题了
但是在实际操作时,发现还是有点问题,有的pdf中字体较多,linux服务器上字体库没有时,当时采用的时icetext的类库,发现当pdf字体icetext无法识别时就会出现乱码,而且生成图片时,是按照pdf一页一张图片生成的,显示不太友好.

需求进一步明确

1.一个pdf文件对应一张图片

2.不能出现乱码

最终发现Apache的,pdfbox支持转出的图片效果比较好,而且也不会乱码,但是pdf对应多个图片
需求2解决了,如何解决一个pdf文件对应一张图片的问题尼?
要是能在内存中把多张图片合并成一张图片就行了,那么怎么才能合并图片尼?
这个其实也不难,之前上学的时候,书本上曾经说个,图片文件就是一个一个的像素点组成的,只能我们能获取并保存每张图片的所有像素点,就可以随时还原这张图片,当然为了保证图片不失真,还需要保存原始宽高.

pdfbox代码实现

代码中采用的时最新的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(); i<len; i++){                 BufferedImage image=renderer.renderImageWithDPI(i, DEFAULT_DPI,ImageType.RGB);                  int 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图片类库,大家使用时可能还需要去挂网下载,简单的操作图片还可以的.

原创粉丝点击