Java PDFToImage

背景 & 需求

业务需要,emmm,好吧挺坑的,项目运营人员不管从哪里下载的PDF,都想统一上传展示,有的很大,有的很长,嗯,没错,不管什么来源,你全给我统一咯(我不管,反正我不懂技术,你给我实现),首先,先来一巴掌(内心里,内心里)

思路 & 调研

  • 首先是,产品也并不希望投入太大的开发成本,所以必然需要运营人员做一步标准化的操作,这一点必须要说明的
  • 前端展示pdf还是有诸多不便,所以换成上传PDF,转化为长图,再来展示
  • PDF转图片有很多现有的工具的(java)
  • 图片清晰度、大小,都可以控制
    调研应该比较全面了,有不足之处,请大佬指正

备选解决方案

主要问题就在于PDF转图片过程中的压缩了,其他的都是可以工具解决,例子也很多

  • 首先,考虑清晰度和体积,前端展示肯定会希望两者兼得,又小有清晰最佳,那么或许矢量图可以胜任。矢量图不怕缩放(其实并非体积)依然可以保持清晰,或许是个很好的选择
  • 其次,是调参方案,根据PDF体积和分辨率划分多个档位,定义不同的压缩级别,实施压缩
    开工尝试!

用到的组件

  • SVG方案
icepdf
jai-imageio-core
jai-imageio-jpeg2000
batik系列组件

其中 batik系列组件是对于svg有很好的支持,生成缩放等等功能都可以支持

  • 调参方案
icepdf
jai-imageio-core
jai-imageio-jpeg2000

开发中遇到的问题(坑)

首先是SVG方案的不可行

SVG方案看似很美好,但是,其实SVG是基于XML的描述性文件(详情请戳)(其他图像是像素文件),所以本质上,SVG是文本文件,并不是一个常规的图像,也就无法完成体积的压缩,所谓的压缩只是去除了头部的metadata的;而且我们需要的是多个图片拼接成一个图片,拼接之后再去转也就没有意义了,因为转完之后的图片足够清晰也就可以了,并没有很大程度的放大需求

当然其实SVG的优点也很明显。它单图体积并不大,我们实例中用到的大概1M左右,无论放大缩小都不会失真,这一点很是优秀的

然后是两个组件的坑

jai_core
jai-imageio-jpeg2000
  • jai_core

jai_core是icepdf的依赖,但其资源难以获取,maven处理过程中会有报错,解决方案有二,其一是我实际开发中其实没有用到,直接不要了


    
        javax.media
        jai_core
    

其二是网络上找到资源,弄到项目里

  • jai-imageio-jpeg2000

转有些PDF时候,会出现转换错误,报错其实很明显,没有jpeg2000的支持,下载如上组件就好

再者是icepdf的坑

生成新图片时候有一句代码

BufferedImage imageResult = new BufferedImage(maxWidth, height, BufferedImage.TYPE_INT_RGB);

看似不经意,但是这个宽高可是像素,当图片分辨率足够高时,这个新生成的数组会有200多M,直接弄爆内存了,所以也就是上述方案中需要根据分辨率动态调整下缩放级别
另,注意主动释放内存,处理的图片很大了,这个问题需要关注了

最后是一个留白问题

PDF中的每一页可能并不都大小相同,所以需要做统一处理,较小的图片做一次留白操作,保证每一个图片宽高都一致,否则拼接时候有可能空指针报错,要小心

收获与不足

收获

  • 图像处理还是一个很常见的需求,积累了经验也是极好的,但是标准化一定要提前做好,不然类似研发还无法取得很好的效果啊
  • 注意内存,之前的需求,可能弄来弄去也就是个不大的数组,没有真的关心过内存等等问题,但其实这个问题一直都在那里,一不注意,就完蛋咯。小心小心再小心,踩过的坑,记忆尤深

不足

  • 及时沉淀,学习让你进步,忘了自然回退,及时沉淀,才能真的掌握住原来不会的,永久化为自己的东西。
  • 多做尝试,不要钻死牛角尖
  • 开发时候要时刻注意代码的封装和结构化,一盘散沙不易维护,堆在一起多了再拆分就费力了。

欢迎大佬们指点
以上,共勉


欢迎大家关注我的公众号


半亩房顶

你可能感兴趣的:(Java PDFToImage)