2011-09-16 47 views
1

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

不用说,它不起作用。流标题都是正确的,但我不认为该流正确压缩以符合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(); 
    } 
} 

回答

0

我已经写在CodePlex上一个library,可以帮助你。

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

+0

Err。对不起,我现在看到你正在用java编程,而不是c#。 – pwizzle

相关问题