从.cbz存档中读取图像

时间:2012-03-10 18:30:15

标签: java image out-of-memory bufferedimage

我想读取.CBZ存档中的图像并将它们存储在ArrayList中。我尝试了以下解决方案,但它至少有2个问题。

  1. 在向ArrayList
  2. 添加10-15个图像后,出现OutOfMemory错误
  3. 必须有一种更好的方法来获取ArrayList中的图像,而不是将它们写在临时文件上并再次读取它。

  4. 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 个答案:

答案 0 :(得分:2)

每个BufferedImage通常比构造它的byte[]需要更多的内存。缓存byte[]并根据需要将每个标记为图像。

答案 1 :(得分:1)

“OutOfMemoryError”可能或者可能不是您尝试存储在内存中的数据量所固有的。您可能需要更改最大堆大小。但是,您当然可以避免写入磁盘 - 只需写入ByteArrayOutputStream,然后您可以将数据作为字节数组获取 - 如果需要,可能会创建ByteArrayInputStream轮。您是否肯定需要将其添加到列表中BufferedImage而不是(比方说)将每个列为byte[]

请注意,如果您能够使用Guava,则可以非常轻松地从“InputStream”位中提取数据:

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