java图片处理以及pdf转图片

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图片类库,大家使用时可能还需要去挂网下载,简单的操作图片还可以的.

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值