私は、スキャンされたPDFを縮小する目的で、より小さいモノクロ(2色B & W)バージョンのPDFに置き換えるユーティリティを開発中です。下記のプログラム(全部)は、大型の.pngファイルにすべての画像をin
ディレクトリにエクスポートします。ユーザーはこれらのファイルを取り込み、必要な画像操作を行い、結果を同じ名前でコピーします。 .jb2
拡張子をout
ディレクトリにコピーします。このプログラムを再度実行すると、変更されたファイルがストリームにコピーされ、元のイメージが置き換えられます。iText経由でJBIG2DECODEストリームとしてPDFに画像を追加するには
言うまでもなく、動作しません。ストリームヘッダーはすべて正しいですが、ストリームが正しくJBIG2DEOCDE
フォーマットに準拠するように圧縮されているとは思わないので、変更された画像はどれもリーダーに表示されません。私は既存のストリームを置き換えているので、私はdocument.add(Image)
を使うことができないので、このストリームのすべてを手作業で行う必要があります。私はこれを行うためのiTextの施設が不足しているかもしれませんが、どうやってこれらの画像をストリームに入れるのですか?
フォーマット.jb2
の形式はiTextによって規定されていましたが、私は同じように、より一般的な形式、たとえば.gif
を簡単に使用できます。重要な点は、B & W 2色パレットの画像をPDFに配置し、白黒のテキスト画像に適した圧縮形式(JBIG2が好きですが、CCITT 3または4またはRLEは私のために働く)。目標は最大の省スペースです。私は処理時間の要件がありません。
また、誰かが私がやろうとしていることをするための良いユーティリティプログラムを知っていれば、それも同様です。 PDFファイル内の既存のイメージをすべて置き換えて(外部アプリケーションで処理できるようにする必要があります)、置き換えの圧縮方法を制御する必要があります。また、バッチモード処理に適した方法で行う必要があります。なぜなら、私は数百のページと1ページあたり1つの画像を持つ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();
}
}
Err。申し訳ありませんが、私はあなたがjavaでプログラミングしているのを見て、C#ではありません。 – pwizzle