スキャンしたPDFを縮小する目的で、PDF内の画像をより小さなモノクロ(2色白黒)バージョンに置き換えるユーティリティに取り組んでいます。以下のプログラム(これがすべてです)は現在、すべての画像を大きな.pngファイルのinディレクトリにエクスポートします。ユーザーはこれらのファイルを取得し、必要な画像操作を行い、結果を同じ名前でコピーしますが、現在はディレクトリ.jb2への拡張子。outこのプログラムを再度実行すると、変更したファイルがストリームにコピーされ、元の画像が置き換えられます。
言うまでもなく、それは機能しません。ストリームヘッダーはすべて正しいですが、ストリームがフォーマットに準拠するように適切に圧縮されているとは思わないJBIG2DEOCDEため、変更された画像はリーダーに表示されません。既存のストリームを置き換えるため、を使用できませんdocument.add(Image)。そのため、このストリームの処理をすべて手動で行う必要があります。これを行うためのiText機能がない可能性がありますが、これらの画像をストリームに取り込むにはどうすればよいですか?
フォーマットの使用法は.jb2iTextによって決定されましたが、私は。のようなより一般的なフォーマットを同じように簡単に使用できます.gif。重要なのは、白黒の2色パレットをPDFに配置し、モノクロのテキスト画像に適した圧縮形式の画像を配置することです(JBIG2が望ましいですが、CCITT3または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();
}
}