2012-03-10 13 views
1

.CBZアーカイブ内の画像を読み取り、それらをArrayList内に保存したいと考えています。私は以下の解決策を試しましたが、少なくとも2つの問題があります。.cbzアーカイブから画像を読み取る

  1. 私は、ArrayListの内の画像を得る代わりに、一時ファイルにそれらを書き込み、それを再度読んでのより良い方法があるに違いありませんArrayListの
  2. に10-15画像を追加した後のOutOfMemoryエラーが発生します。

public class CBZHandler { 
final int BUFFER = 2048; 
ArrayList<BufferedImage> images = new ArrayList<BufferedImage>(); 

public void extractCBZ(ZipInputStream tis) throws IOException{ 
    ZipEntry entry; 
    BufferedOutputStream dest = null; 
    if(!images.isEmpty()) 
     images.clear(); 
    while((entry = tis.getNextEntry()) != null){ 
     System.out.println("Extracting " + entry.getName()); 
     int count; 
     FileOutputStream fos = new FileOutputStream("temp"); 
     dest = new BufferedOutputStream(fos,BUFFER); 
     byte data[] = new byte[BUFFER]; 
     while ((count = tis.read(data, 0, BUFFER)) != -1) { 
       dest.write(data, 0, count); 
      } 
     dest.flush(); 
     dest.close(); 
     BufferedImage img = ImageIO.read(new FileInputStream("temp")); 
     images.add(img); 
    } 
    tis.close(); 
} 
} 
+1

ImageIOはInputStreamから読み取ります。なぜImageIO.read()にZipInputStream( 'tis')を渡さないのですか?イメージのサイズ(バイト単位)は何ですか?また、JVMのヒープのサイズは何ですか? –

+0

これらの画像の解像度(幅*高さ、多分*色深度)を知ることは、メモリ使用量の見積もりにも役立ちます。 –

答えて

1

「OutOfMemoryErrorが」よく、またはあなたがメモリに格納しようとしているデータの量に固有ではないかもしれません。最大ヒープサイズを変更する必要があるかもしれません。しかし、確実にディスクへの書き込みを避けることができます。代わりにByteArrayOutputStreamに書き込むだけで、データをバイト配列として取得することができます。必要に応じてByteArrayInputStreamを作成する可能性があります。それぞれをbyte[]として保存するのではなく、BufferedImageとしてリストに追加する必要がありますか?あなたがGuavaを使用することができるしている場合、それは少し非常に簡単「InputStreamから抽出データ」を作ること

注:

byte[] data = ByteStreams.toByteArray(tis); 
+0

私はOOMを実行するのが奇妙に見えます。なぜなら、そのルーチンはすべて私のコードが今までのことだからです。 ByteArrayOutputStreamヒントありがとう。それらをバイトとして格納する利点は何ですか? – tagomago

+0

@AlfioCastorina:これらは高レベルの圧縮を持ついくつかの画像であると想像してください。「BufferedImage」は、それを各ピクセルのメモリ内ビットマップ表現に変換している可能性があります。ファイル。 –

2

は各BufferedImageは、典型的には、それがあるからbyte[]よりも有意に多くのメモリが必要になります構築された。 byte[]をキャッシュし、必要に応じてそれぞれの画像にスタンプする。

関連する問題