如何通过 iText 将黑白图像作为JBIG2DECODE流添加到 PDF 中



我正在开发一个实用程序,用于将PDF中的图像替换为较小的单色(2色B&W)版本,以缩小扫描的PDF。下面的程序(这是整个事情)当前将所有图像导出为大型。png文件到in目录,因此用户获取这些文件,执行任何必要的图像操作,并将结果复制到out目录,具有相同的名称,但现在具有.jb2扩展名。再次运行此程序应该将修改后的文件复制回流,替换原始图像。

不用说,它不起作用。流头都是正确的,但我不认为流被正确压缩以符合JBIG2DEOCDE格式,所以没有修改的图像显示在阅读器中。因为我要替换一个现有的流,我不能使用document.add(Image),所以我必须手动做所有这些流的东西。我可能缺少用于此操作的iText工具,但是我应该如何将这些图像放入流中呢?

.jb2格式的使用是由iText决定的,但我可以很容易地使用更常见的格式,如.gif。重要的部分是,我想要一个带有B&W两色调色板的图像放在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();
    }
}

我在codeplex上写了一个库,可能会对你有所帮助。

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

相关内容

  • 没有找到相关文章

最新更新