Как добавить черно-белые изображения в виде потоков JBIG2DECODE в PDF через iText

Я работаю над утилитой для замены изображений в PDF на меньшие монохромные (двухцветные черно-белые) версии с целью сокращения отсканированных PDF-файлов. Приведенная ниже программа (и это все) в настоящее время экспортирует все изображения в большие файлы.png в in каталог, в котором пользователь берет эти файлы, выполняет любые необходимые манипуляции с изображениями и копирует результаты с теми же именами, но теперь с .jb2 расширение, до out каталог. Повторный запуск этой программы должен скопировать измененные файлы обратно в поток, заменив исходные изображения.

Излишне говорить, что это не работает. Заголовки потока все правильные, но я не думаю, что поток правильно сжат, чтобы соответствовать JBIG2DEOCDE формат, поэтому ни одно из измененных изображений не отображается в считывателе. Поскольку я заменяю существующий поток, я не могу использовать document.add(Image)так что я должен делать все эти потоковые вещи вручную. Возможно, мне не хватает средства iText для этого, но как я могу получить эти изображения в поток?

Использование .jb2 формат был продиктован iText, но я также легко могу использовать более распространенный формат, такой как .gif, Важной частью является то, что я хочу, чтобы изображение с черно-белой 2-цветовой палитрой было помещено в PDF-файл и формат сжатия, подходящий для монохромных текстовых изображений (я бы предпочел JBIG2, но CCITT 3, 4 или RLE будут работать для я тоже). Цель - максимальная экономия места; У меня нет требований к времени обработки.

В качестве альтернативы, если кто-нибудь знает какие-либо хорошие утилиты, которые делают то, что я пытаюсь сделать, это было бы также хорошо. Я хочу заменить все существующие изображения в файле PDF на альтернативные (они должны быть доступны для обработки внешним приложением), и мне нужно контролировать, как сжимаются замены. Это также должно быть сделано способом, подходящим для обработки в пакетном режиме, потому что я имею дело с PDF-файлами с сотнями страниц и одним изображением на странице, как правило. Я пытаюсь уменьшить размер моих PDF-файлов, но мне нужен полный контроль над сжатием, и я хочу сделать все сжатие с потерями самостоятельно. Функция Acrobat "Уменьшить размер PDF" всегда искажает мои изображения.

public class Test {
    public static void main(String[] args) throws IOException, DocumentException
    {
        PdfReader pdf = new PdfReader("data\\in.pdf");
        int n = pdf.getXrefSize();
        for (int i = 0; i < n; i++) {
            PdfObject object = pdf.getPdfObject(i);
            if (object == null || !object.isStream()) continue;
            PRStream stream = (PRStream)object;
            if (!stream.contains(PdfName.WIDTH)) continue;
            PdfImageObject image = new PdfImageObject(stream);
            BufferedImage bi = image.getBufferedImage();
            if (bi == null) continue;
            File in = new File("data\\in\\" + i + ".png");
            if (!in.exists()) {
                ImageIO.write(bi, "png", in);
            }
            File out = new File("data\\out\\" + i + ".jb2");
            if (!out.exists()) continue;
            Image img = Image.getInstance("data\\out\\" + i + ".jb2");
            byte[] data = new byte[(int)out.length()];
            new FileInputStream(out).read(data);
            stream.clear();
            stream.setData(data, false, PRStream.NO_COMPRESSION);
            stream.put(PdfName.TYPE, PdfName.XOBJECT);
            stream.put(PdfName.SUBTYPE, PdfName.IMAGE);
            stream.put(PdfName.FILTER, PdfName.JBIG2DECODE);
            stream.put(PdfName.WIDTH, new PdfNumber((int)img.getWidth()));
            stream.put(PdfName.HEIGHT, new PdfNumber((int)img.getHeight()));
            stream.put(PdfName.BITSPERCOMPONENT, new PdfNumber(1));
            stream.put(PdfName.COLORSPACE, PdfName.DEVICEGRAY);
        }
        new PdfStamper(pdf, new FileOutputStream("data\\out.pdf")).close();
    }
}

1 ответ

Я написал библиотеку на codeplex, которая может вам помочь.

Он используется для распознавания и сжатия отсканированных PDF-файлов с помощью jbig2 и имеет делегата для некоторой обработки изображения перед его добавлением в PDF-файл.

Другие вопросы по тегам