java - 如何减小合并后的 pdf 大小并加快与 PDFBox 的合并操作?
问题描述
我们正在使用 PDFBox 2.0.17(主要原因:免费)和 java 8 来合并两种类型的 PDF 文档(普通 PDF/A 和从 Tiff 文件转换的 PDF)。
我们发现生成的 PDF 文件的大小相当大 - 基本上是所有 PDF 的总大小。我正在尝试找到一种方法来减小生成的文件大小。
我找到了一个 stackoverflow 链接如何使用 pdfbox 或其他 java 库减小合并的 PDF/A-1b 文件的大小。但这似乎没有帮助。
有什么方法可以通过以下方式减小生成的 PDF 的大小?
- 字体优化、图像优化和压缩 PDF 压缩
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
public class MergerTest {
public static void main(String[] args) throws IOException {
File file1 = new File("C:\\Test\\PdfBox_Examples\\doc1.pdf");
File file2 = new File("C:\\Test\\PdfBox_Examples\\doc2.pdf");
//Instantiating PDFMergerUtility class
PDFMergerUtility PDFmerger = new PDFMergerUtility();
//Setting the destination file
PDFmerger.setDestinationFileName("C:\\Test\\PdfBox_Examples\\merged.pdf");
//adding the source files
PDFmerger.addSource(file1);
PDFmerger.addSource(file2);
//Merging the two documents
PDFmerger.mergeDocuments(null);
System.out.println("Documents merged");
File file = new File("C:\\Test\\PdfBox_Examples\\merged.pdf");
PDDocument doc = PDDocument.load(file);
Map<String, COSBase> fontFileCache = new HashMap<>();
for (int pageNumber = 0; pageNumber < doc.getNumberOfPages();
pageNumber++) {
final PDPage page = doc.getPage(pageNumber);
COSDictionary pageDictionary = (COSDictionary)
page.getResources().getCOSObject().getDictionaryObject
(COSName.FONT);
if(pageDictionary !=null) {
for (COSName currentFont : pageDictionary.keySet()) {
COSDictionary fontDictionary = (COSDictionary)
pageDictionary.getDictionaryObject(currentFont);
for (COSName actualFont : fontDictionary.keySet()) {
COSBase actualFontDictionaryObject =
fontDictionary.getDictionaryObject(actualFont);
if (actualFontDictionaryObject instanceof COSDictionary)
{
COSDictionary fontFile = (COSDictionary)
actualFontDictionaryObject;
if (fontFile.getItem(COSName.FONT_NAME) instanceof
COSName) {
COSName fontName = (COSName)
fontFile.getItem(COSName.FONT_NAME);
fontFileCache.computeIfAbsent(fontName.getName(), key ->
fontFile.getItem(COSName.FONT_FILE2));
fontFile.setItem(COSName.FONT_FILE2,
fontFileCache.get(fontName.getName()));
}
}
}
}
}else {
System.out.println("pageDictionary is null - likely Converted PDF
from Tiff");
}
}
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.save(baos);
final File compressed = new
File("C:\\Test\\PdfBox_Examples\\test_compressed.pdf");
baos.writeTo(new FileOutputStream(compressed));
System.out.println("Documents compressed");
}
}
//注意:我还使用 tiff_1.pdf 和 tiff_2.pdf 作为输入进行了测试。
解决方案
推荐阅读
- matlab - How to store complex data into an array using a For loop?
- python - How to merge 2 numpy ndarray on a ndarray using values of a column?
- javascript - Jquery triggering specific li on click for Bootstrap dropdown
- angular - ngx-markdown-editor 元数据版本不匹配错误
- python - Python 3 中的“优先级堆栈”(优先级队列和堆栈的混合体)?
- excel - 运行时错误 91 帮助
- javascript - React ref with an id as attribute value
- erlang - 在非 NixOS 系统上使用 `nix` 安装 Elixir 或 Erlang > 19 的规范方法是什么?
- python - Uploading .csv to Google Sheets via Gspread
- java - How can I convert an IEEE-754 binary representation String to a float or double in Java?