Чтение изображений из архива .cbz - PullRequest
1 голос
/ 10 марта 2012

Я хочу прочитать изображения в архиве .CBZ и сохранить их в ArrayList.Я попробовал следующее решение, но у него есть, по крайней мере, 2 проблемы.

  1. Я получаю ошибку OutOfMemory после добавления 10-15 изображений в ArrayList
  2. Должен быть лучший способ получения изображений внутри ArrayList вместо записи их во временный файли читая это снова.

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();
}
}

Ответы [ 2 ]

2 голосов
/ 10 марта 2012

Каждый BufferedImage обычно требует значительно больше памяти, чем byte[], из которого он построен. Кэшируйте byte[] и печатайте каждый из них на изображение при необходимости.

1 голос
/ 10 марта 2012

«OutOfMemoryError» может или может не зависеть от объема данных, которые вы пытаетесь сохранить в памяти.Возможно, вам придется изменить максимальный размер кучи.Тем не менее, вы, безусловно, можете избежать записи на диск - просто вместо этого запишите в ByteArrayOutputStream, тогда вы можете получить данные в виде байтового массива - потенциально создавая ByteArrayInputStream вокруг него, если вам нужно.Вам определенно нужно добавить их в свой список как BufferedImage вместо того, чтобы (скажем) сохранить каждый из них как byte[]?

Обратите внимание, что если вы можете использовать Guava делает бит извлечения данных из InputStream очень простым:

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