一、需求

项目中需要将文件大小过大的PDF文件,压缩成小PDF文件。通过iText的API,可以实现此需求。在保证文件不失真的前提下,将PDF大文件压缩成小文件。

二、代码

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.parser.PdfImageObject;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class TestReduceImgDemoSuccess {/*** 图像的乘法因子*/public static float FACTOR = 0.5f;/***** @param src  源文件* @param dest 目标文件* @throws IOException* @throws DocumentException*/public void manipulatePdf(String src, String dest) throws IOException, DocumentException {PdfName key = new PdfName("ITXT_SpecialId");PdfName value = new PdfName("123456789");// 读取pdf文件PdfReader reader = new PdfReader(src);int n = reader.getXrefSize();PdfObject object;PRStream stream;// Look for image and manipulate image streamfor (int i = 0; i < n; i++) {object = reader.getPdfObject(i);PdfObject pdfObject = reader.getPdfObject(i);if (object == null || !object.isStream())continue;stream = (PRStream) object;PdfObject pdfsubtype = stream.get(PdfName.SUBTYPE);System.out.println(stream.type());if (pdfsubtype != null && pdfsubtype.toString().equals(PdfName.IMAGE.toString())) {PdfImageObject image = new PdfImageObject(stream);BufferedImage bi = image.getBufferedImage();if (bi == null) continue;int width = (int) (bi.getWidth() * FACTOR);int height = (int) (bi.getHeight() * FACTOR);BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);AffineTransform at = AffineTransform.getScaleInstance(FACTOR, FACTOR);Graphics2D g = img.createGraphics();g.drawRenderedImage(bi, at);ByteArrayOutputStream imgBytes = new ByteArrayOutputStream();//标记此处,后面会修改ImageIO.write(img, "JPG", imgBytes);stream.clear();stream.setData(imgBytes.toByteArray(), false, PRStream.BEST_COMPRESSION);stream.put(PdfName.TYPE, PdfName.XOBJECT);stream.put(PdfName.SUBTYPE, PdfName.IMAGE);stream.put(key, value);stream.put(PdfName.FILTER, PdfName.DCTDECODE);stream.put(PdfName.WIDTH, new PdfNumber(width));stream.put(PdfName.HEIGHT, new PdfNumber(height));stream.put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));stream.put(PdfName.COLORSPACE, PdfName.DEVICERGB);}}// Save altered PDFPdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));stamper.close();reader.close();}/*** Main method.** @param args no arguments needed* @throws DocumentException* @throws IOException*/public static void main(String[] args) throws IOException, DocumentException {//createPdf(RESULT);new TestReduceImgDemoSuccess().manipulatePdf("源文件存储的路径,例如D:/xxx/xx.pdf","目标文件的存储路径,例如D:/xxx/result.pdf");}}

三、出现的问题

此代码的原理简单来说就是把PDF文件转化成图片流,然后再把图片流输出成PDF文件,可以实现将大PDF文件压缩成小PDF文件。但是如果文件过小可能会出现失真。解决办法为在压缩文件之前,判断一下每个图片文件流的大小,如果过于小(此处假设为500k,可根据业务需要进行设定),就不需要再压缩,只对过大的图片进行压缩。

四、解决办法

再上面代码的标记处,修改如下代码:

                ByteArrayOutputStream imgBytes = new ByteArrayOutputStream();//判断文件流的大小,超过500k的才进行压缩,否则不进行压缩if(img.getData().getDataBuffer().getSize()>512000){ImageIO.write(img, "JPG", imgBytes);stream.clear();stream.setData(imgBytes.toByteArray(), false, PRStream.BEST_COMPRESSION);stream.put(PdfName.TYPE, PdfName.XOBJECT);stream.put(PdfName.SUBTYPE, PdfName.IMAGE);stream.put(key, value);stream.put(PdfName.FILTER, PdfName.DCTDECODE);stream.put(PdfName.WIDTH, new PdfNumber(width));stream.put(PdfName.HEIGHT, new PdfNumber(height));stream.put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));stream.put(PdfName.COLORSPACE, PdfName.DEVICERGB);}else {ImageIO.write(img, "JPG", imgBytes);}

使用java iTest实现PDF大文件压缩——将文件过大的图片PDF文件压缩成小一些的图片PDF文件相关推荐

  1. cdr文件太大怎么转成小内存 CDR文件太大打不开怎么办

    使用cdr软件制作图形时,常常会将其制作成矢量图形.虽然矢量图形有着不失真.可任意放大等优点,但常会导致cdr文件过大.那么,cdr文件太大怎么转成小内存,CDR文件太大打不开怎么办?本文将会针对以上 ...

  2. pdf太大怎么压缩大小?pdf文件压缩后还是太大怎么办?

    pdf太大怎么压缩大小?pdf文件压缩后还是太大怎么办?无论是什么文件,一旦文件体积过大就会很麻烦.比如一份PDF文件比较大,网速不好的话传输就很慢.遇到这种情况,我们可以选择对这样的PDF文件进行压 ...

  3. java下载图片压缩包_java压缩文件和下载图片示例

    本文实例为大家分享了java压缩文件和下载图片示例,供大家参考,具体内容如下 主页面index.xml 项目的主页 主页主页 湖南长沙 发布方式一...... 页面内容压缩演示--gzip 下载图片 ...

  4. java实现把一个大文件切割成N个固定大小的文件

    这个好像是我一年前去面试时的一道面试题,分享一下!考 java I/O 的! //java实现把一个大文件切割成N个固定大小的文件 package com.johnny.test; import ja ...

  5. SQLSERVER压缩数据文件的用处有多大

    SQLSERVER压缩数据文件的用处有多大 前奏: 前些天因为客户那边的问题(其实是盗版问题),只能使用免费的SQLSERVER EXPRESS版本 SQLSERVER2005 的express版本的 ...

  6. js 导出pdf上传至oss_前端上传图片到oss,压缩图片后上传至oss(补充图片文件旋转90度问题)...

    上传图片如果过大,等待时间过长体验不好,于是使用js压缩图片再上传,无关图片清晰度. /** * 压缩图片 * @param file 图片文件 * @param callback 回调函数,压缩完要 ...

  7. java流式上传下载_精讲RestTemplate第6篇-文件上传下载与大文件流式下载

    C++Templates(第2版英文版) 123.24元 (需用券) 去购买 > 本文是精讲RestTemplate第6篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在S ...

  8. 如何将大的视频文件压缩成小的视频文件?

    如何将大的视频文件压缩成小的视频文件?视频是我们在生活中不可或缺的一部分,随着制作视频的小伙伴越来越多,大家都想把制作好的视频上传到一些平台或传给别人,有时候我们会遇到视频内存过大的问题,今天我给大家 ...

  9. C++ minizip的简单使用,zip文件的创建、读取、修改、密码压缩、4G以上大文件压缩。

    兄弟姐妹们好,深夜党又来记录枯燥的编程生活了.今天给大家带来的是minizip库,一个解压和压缩文件的开源代码库,如题目所示的结构来介绍.你可以在下面的链接搜索到minizip库: http://ww ...

最新文章

  1. maven打包跳过Test
  2. MongoDB服务启动与停止命令(Windows环境)
  3. 22考生这些院校计算机专业改考408
  4. 【图论】旅行者(P5304)
  5. 比特币:生于 2009,亡于 2016?
  6. java封装需要多久_Java对时间操作的一些封装函数
  7. Linux之虚拟机配置双网卡
  8. 蓝桥杯 基础练习 芯片测试
  9. 华为机试HJ42:学英语
  10. Intellij IDEA 配置 Code Style
  11. linux文件系统 - 初始化(一)
  12. 为什么少有人在Windows电脑上安OS X?
  13. 代码雨代码源复制_黑色帝国中代码雨如何实现?用python就可以了
  14. Python实战案例:金庸的功夫流派、人物关系的分析案例(下)
  15. win10很多软件显示模糊_win10系统字体模糊的解决方法
  16. 逻辑覆盖:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖和路径覆盖
  17. python统计三国演义中人物出现的频次
  18. 7z 类库解析之 Format7zF 工程
  19. 硅谷丛林的故事 EDA篇
  20. 是女人,请进来学学拍照姿势!

热门文章

  1. RK3568平台开发系列讲解(设备驱动篇)V4L2程序实现流程
  2. linux 16.04系统下载,ubuntu16.04镜像下载
  3. 装完系统安装完驱动后重启进入系统蓝屏0X000000A5
  4. 新福华无纺布周利民之十二生肖(羊)
  5. pytorch __getitem__ 返回值
  6. 王冠逸亮相日内瓦表展 海兰察与金刚狼打破次元壁get同框
  7. nodejs如何创建桌面快捷方式
  8. 苹果6s强制删除id锁_新店开业换苹果大容量电池只需80元
  9. 视频封面图片修改html代码,canvas绘制视频封面的方法
  10. i5 1240p和酷睿i7 1195g7 选哪个好?区别对比评测