1

我正在开发一个实用程序,用较小的单色(2 色黑白)版本替换 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();
    }
}
4

1 回答 1

0

我在 codeplex 上写了一个库,可以帮助你。

它用于使用 jbig2 对扫描的 PDF 进行 OCR 处理和压缩,并且在将图像添加到 pdf 之前,它有一个委托对图像进行一些处理。

于 2012-05-06T00:34:26.450 回答