Как уменьшить размер выходного PDF при привязке одного и того же PDF много раз Java - PullRequest
0 голосов
/ 19 июня 2019

Я пытаюсь написать подшивку в java для создания слоя «два вверх», использующего много раз одну и ту же проблему pdf: размер файла слишком велик, как его оптимизировать?

Я поставил SmartMode, но не помог.

String infile = "D:\\libro\\libro.pdf";
String outfile = "D:\\libro\\test_out.pdf";
FileOutputStream output = new FileOutputStream(outfile);
PdfDocument pdfDoc = new PdfDocument(new  PdfWriter(outfile).setSmartMode(true));
pdfDoc.setDefaultPageSize(PageSize.A2.rotate());
PdfPage pageorig, pagenew;
PdfCanvas canvas;
PdfDocument reader = new PdfDocument(new PdfReader(infile));

int pages = reader.getNumberOfPages();
for (int j = 0; j < 10; j++) {
    for (int i = 1; i <= pages; i++) {

        pageorig = reader.getPage(i);
        pagenew = pdfDoc.addNewPage();
        canvas = new PdfCanvas(pagenew);

        canvas.addXObject(pageorig.copyAsFormXObject(pdfDoc), 0, 0);
        canvas.addXObject(pageorig.copyAsFormXObject(pdfDoc), pageorig.getPageSize().getWidth(), 0);

    }
}
pdfDoc.close();
reader.close();

Исходный размер PDF составляет 20 МБ, если сделать одну копию, выходной файл будет 19 МБ, НО, если я сделаю 10 копий, выходной файл будет 83 МБ.. это очень большой

РЕДАКТИРОВАТЬ: ссылка на PDF используется PDF

1 Ответ

1 голос
/ 23 июня 2019

Простая алгоритмическая оптимизация помогает здесь значительно ускорить выполнение кода и решить вашу проблему с помощью результирующего размера файла.Вместо того, чтобы делать новую копию страницы каждый раз, когда вы хотите вставить ее (по сути, 10 * 2 раза), вы можете сделать копию каждой страницы один раз, а затем использовать ее 10 * 2 раза.В моем коде я использую ленивое кэширование с Map и делаю копию, когда мы пропустили (страница еще не была скопирована).Это можно было бы сделать и другим способом - пропустив страницы документа и предварительно сделав новую копию.

Вот оптимизированная версия кода:

String infile = "D:\\libro.pdf";
String outfile = "D:\\test_out.pdf";
PdfDocument pdfDoc = new PdfDocument(new  PdfWriter(outfile).setSmartMode(true));
pdfDoc.setDefaultPageSize(PageSize.A2.rotate());
PdfPage pageorig, pagenew;
PdfCanvas canvas;
PdfDocument reader = new PdfDocument(new PdfReader(infile));

// Caching page copies
Map<Integer, PdfFormXObject> pageCopies = new HashMap<>();

int pages = reader.getNumberOfPages();
for (int j = 0; j < 10; j++) {
    for (int i = 1; i <= pages; i++) {
        pageorig = reader.getPage(i);
        PdfFormXObject origPageCopy = pageCopies.get(i);
        // Cache miss, doing a fresh copy
        if (origPageCopy == null) {
            origPageCopy = pageorig.copyAsFormXObject(pdfDoc);
            pageCopies.put(i, origPageCopy);
        }

        pagenew = pdfDoc.addNewPage();
        canvas = new PdfCanvas(pagenew);

        canvas.addXObject(origPageCopy, 0, 0);
        canvas.addXObject(origPageCopy, pageorig.getPageSize().getWidth(), 0);
    }
}
pdfDoc.close();
reader.close();

На моемрезультирующий размер файла составляет ~ 15 МБ, даже меньше исходного размера файла.Кроме того, этот код выполняется за ~ 3 секунды по сравнению с ~ 25 секундами с исходной версией кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...