Как добавить черно-белые изображения в виде потоков JBIG2DECODE в PDF через iText - PullRequest
1 голос
/ 17 сентября 2011

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

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

Использование формата .jb2 было продиктовано iText, но я так же легко могу использовать более распространенный формат, такой как .gif. Важная часть заключается в том, что я хочу, чтобы изображение с черно-белой палитрой черно-белых изображений помещалось в 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 Ответ

0 голосов
/ 06 мая 2012

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

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

...