通过Java使用大图像压缩pdf

寻找一种将图像压缩为pdf格式并输出pdf进行存档的方法。我无法在创建图像之前对其进行压缩,因为这会影响打印质量。

每个pdf的大小约为8MB,其中大部分由2张图片组成。图片为png格式,并在生成过程中转换为pdf(使用了第三方生成器)

有没有一种方法可以在不使用第3方工具的情况下用Java压缩它们。我尝试使用pdfbox,itext和第3方exe(neevia),第3方工具是迄今为止唯一给我任何结果的工具(降低到大约一半MB),但我不想放弃对exe的控制。示例代码如下。

import java.io.BufferedReader;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.util.Arrays;

import org.apache.pdfbox.exceptions.COSVisitorException;

import org.apache.pdfbox.pdmodel.PDDocument;

import org.apache.pdfbox.pdmodel.common.PDStream;

import com.itextpdf.text.DocumentException;

import com.itextpdf.text.pdf.PdfReader;

import com.itextpdf.text.pdf.PdfStamper;

import com.itextpdf.text.pdf.PdfWriter;

public class compressPDF {

public static void main (String[] args) throws IOException, DocumentException, COSVisitorException {

/*

* Using PDF Box

*/

PDDocument doc; // = new PDDocument();

doc = PDDocument.load("C:/_dev_env_/TEMP/compressPDF/TRPT_135002_1470_20131212_121423.PDF");

PDStream stream= new PDStream(doc);

stream.addCompression();

doc.save("C:/_dev_env_/TEMP/compressPDF/compressed_pdfBox.pdf");

doc.close();

/*

* Using itext

*/

PdfReader reader = new PdfReader("C:/_dev_env_/TEMP/compressPDF/TRPT_135002_1470_20131212_121423.PDF");

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("C:/_dev_env_/TEMP/compressPDF/compressed_Itext.pdf"), PdfWriter.VERSION_1_5);

stamper.setFullCompression();

stamper.getWriter().setCompressionLevel(50);

int total = reader.getNumberOfPages() + 1;

for (int i = 1; i < total; i++) {

reader.setPageContent(i, reader.getPageContent(i));

}

stamper.close();

reader.close();

/*

* Using 3rd party - Neevia

*/

try {

Process process = new ProcessBuilder("C:/Program Files (x86)/neeviaPDF.com/PDFcompress/cmdLine/CLcompr.exe","C:/_dev_env_/TEMP/compressPDF/TRPT_135002_1470_20131212_121423.PDF", "C:/_dev_env_/TEMP/compressPDF/compressed_Neevia.pdf").start();

InputStream is = process.getInputStream();

InputStreamReader isr = new InputStreamReader(is);

BufferedReader br = new BufferedReader(isr);

String line;

System.out.printf("Output of running %s is:", Arrays.toString(args));

while ((line = br.readLine()) != null) {

System.out.println(line);

}

} catch (Exception e) {

System.out.println(e);

} finally {

System.out.println("Created!!");

}

}

}

回答:

我使用下面的代码进行概念验证…起作用了:)感谢Bruno为我设定了正确的路径:)

package compressPDF;

import java.awt.Graphics2D;

import java.awt.geom.AffineTransform;

import java.awt.image.BufferedImage;

import java.io.ByteArrayOutputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import javax.imageio.ImageIO;

import com.itextpdf.text.DocumentException;

import com.itextpdf.text.pdf.PRStream;

import com.itextpdf.text.pdf.PdfName;

import com.itextpdf.text.pdf.PdfNumber;

import com.itextpdf.text.pdf.PdfObject;

import com.itextpdf.text.pdf.PdfReader;

import com.itextpdf.text.pdf.PdfStamper;

import com.itextpdf.text.pdf.parser.PdfImageObject;

public class ResizeImage {

/** The resulting PDF file. */

//public static String RESULT = "results/part4/chapter16/resized_image.pdf";

/** The multiplication factor for the image. */

public static float FACTOR = 0.5f;

/**

* Manipulates a PDF file src with the file dest as result

* @param src the original PDF

* @param dest the resulting PDF

* @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");

// Read the file

PdfReader reader = new PdfReader(src);

int n = reader.getXrefSize();

PdfObject object;

PRStream stream;

// Look for image and manipulate image stream

for (int i = 0; i < n; i++) {

object = reader.getPdfObject(i);

if (object == null || !object.isStream())

continue;

stream = (PRStream)object;

// if (value.equals(stream.get(key))) {

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 PDF

PdfStamper 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 ResizeImage().manipulatePdf("C:/_dev_env_/TEMP/compressPDF/TRPT_135002_1470_20131212_121423.PDF", "C:/_dev_env_/TEMP/compressPDF/compressTest.pdf");

}

}

以上是 通过Java使用大图像压缩pdf 的全部内容, 来源链接: utcz.com/qa/417095.html

回到顶部