1

いくつかのjava.awt.Imageオブジェクトをディスクに保存したいと思います。しかし、私が次のようにしようとすると:

for (Image image : images) {
    image = new ImageIcon(image).getImage();
    BufferedImage temp = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
    Graphics2D g = temp.createGraphics();
    g.drawImage(image, 0, 0, null);
    g.dispose();
    File tempFile = null;
    try {
        tempFile = File.createTempFile("img", ".jpg");
        ImageIO.write(temp, "jpg", tempFile);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    files.add(tempFile);
}

Javaヒープスペースエラーが発生します。

私は置く必要がありました

image = new ImageIcon(image).getImage();

image.getwidth(null)とimage.getHeight(null)が有効な結果を返すように、すべてのピクセルをロードします。

ヒープサイズを増やす以外に、これを行う他の方法はありますか?

4

2 に答える 2

1

あなたの問題は、スキャナー画像が巨大であるという ことです-600 dpiで、私たちはカラーA4ページごとに100MB以上の非圧縮を話している。優れたスキャナーは、数千DPIでスキャンを取得できます。2000DPIでは、1つの非圧縮カラーページは1GBを超えます。質の高いスキャンのサイズは、最初に作業を開始したときに準備ができていないほとんどの人を捕らえます。

ギグとギグのRAMを備えた64ビットオペレーティングシステムを実行している場合を除いて、メモリに数枚以上の画像を収めることはできません。白黒またはグレースケールで低解像度でスキャンすると役立ちますが、最善の解決策は画像の処理方法を変更することです。

メモリ内の画像のコレクションを取得しないでください。一度に各画像の一部を取得し、完了するまで画像を書き出します。TWAINドライバーとAPIを機能させる-完了するまで、画像の一部を含むバッファーを渡します。独自の画像処理を行うよりも、Javaライブラリを使用してこれを行う方がおそらく良いでしょう。


編集:JavaTWAINライブラリへのリンク

于 2009-08-03T15:57:58.123 に答える
1

コレクション内のすべての画像を保持しないことで、ヒープを節約できる可能性があります。代わりに、取得した各画像を取得して書き込みます。私が提案したコードのhasMoreImages()scanner.getNextImage()の部分は、これの可能な実装の 1 つです。

また、すでに ImageIO で書き込める状態になっている可能性がある場合に、Graphics コンテキストでイメージを描画することの賢明さにも疑問を投げかけます。ImageIO.write() は RenderedImage を必要とするため、簡単なインスタンス チェックで十分な場合があります。

while( hasMoreImages() ) {
    Image image = scanner.getNextImage();

    if ( image instanceof RenderedImage) ) {
        File tempFile = File.createTempFile( "img", ".jpg" );
        ImageIO.write( (RenderedImage)image, "jpg", tempFile );
        files.add( tempFile );
    } else {
        // Do your ImageIcon code thing here.
    }
}
于 2009-08-02T20:19:57.680 に答える