背景 & 需求
业务需要,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处理过程中会有报错,解决方案有二,其一是我实际开发中其实没有用到,直接不要了
<exclusions>
<exclusion>
<groupId>javax.media</groupId>
<artifactId>jai_core</artifactId>
</exclusion>
</exclusions>
其二是网络上找到资源,弄到项目里
- jai-imageio-jpeg2000
转有些PDF时候,会出现转换错误,报错其实很明显,没有jpeg2000的支持,下载如上组件就好
再者是icepdf的坑
生成新图片时候有一句代码
BufferedImage imageResult = new BufferedImage(maxWidth, height, BufferedImage.TYPE_INT_RGB);
看似不经意,但是这个宽高可是像素,当图片分辨率足够高时,这个新生成的数组会有200多M,直接弄爆内存了,所以也就是上述方案中需要根据分辨率动态调整下缩放级别
另,注意主动释放内存
,处理的图片很大了,这个问题需要关注了
最后是一个留白问题
PDF中的每一页可能并不都大小相同,所以需要做统一处理,较小的图片做一次留白操作,保证每一个图片宽高都一致,否则拼接时候有可能空指针报错,要小心
收获与不足
收获
- 图像处理还是一个很常见的需求,积累了经验也是极好的,但是
标准化
一定要提前做好,不然类似研发还无法取得很好的效果啊 -
注意内存
,之前的需求,可能弄来弄去也就是个不大的数组,没有真的关心过内存等等问题,但其实这个问题一直都在那里,一不注意,就完蛋咯。小心小心再小心,踩过的坑,记忆尤深
不足
-
及时沉淀
,学习让你进步,忘了自然回退,及时沉淀,才能真的掌握住原来不会的,永久化为自己的东西。 多做尝试,不要钻死牛角尖
-
开发时候要时刻注意代码的封装和结构化
,一盘散沙不易维护,堆在一起多了再拆分就费力了。
欢迎大佬们指点
以上,共勉
欢迎大家关注我的公众号
半亩房顶
网友评论