序列化包含BufferedImages的对象

时间:2015-08-19 11:40:51

标签: java file bufferedimage

正如标题所暗示的那样,我正在尝试保存文件中包含(包括其他变量,字符串等)一些BufferedImages的对象。

我发现了这个: How to serialize an object that includes BufferedImages

它就像一个魅力,但有一个小小的挫折:如果你的对象只包含一个图像,它会很好。

我一直在努力让他的解决方案能够使用多个图像(理论上应该可以工作),但每次我读取文件时,我都会得到我的对象,我得到正确数量的图像,但是实际上只有第一个图像被读入;其他只是空图像,其中没有数据。

这就是我的对象的样子:

 class Obj implements Serializable
    {
transient List<BufferedImage> imageSelection= new ArrayList<BufferedImage>();
     // ... other vars and functions

private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeInt(imageSelection.size()); // how many images are serialized?
        for (BufferedImage eachImage : imageSelection) {
            ImageIO.write(eachImage, "jpg", out); // png is lossless
        }
    }

 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        final int imageCount = in.readInt();
        imageSelection = new ArrayList<BufferedImage>(imageCount);
        for (int i=0; i<imageCount; i++) {
            imageSelection.add(ImageIO.read(in));
        }
    }

    }

这就是我在文件中写入和读取对象的方式:

// writing
try (
              FileOutputStream file = new FileOutputStream(objName+".ser");
              ObjectOutputStream output = new ObjectOutputStream(file);
            ){
              output.writeObject(myObjs);
            }  
            catch(IOException ex){
              ex.printStackTrace();
            }

// reading
try(
                    FileInputStream inputStr = new FileInputStream(file.getAbsolutePath());
                    ObjectInputStream input = new ObjectInputStream (inputStr);
                    )
                    {myObjs = (List<Obj>)input.readObject();}
                catch(Exception ex)
                    {ex.printStackTrace();}

即使我有一个对象列表,它们也会被正确读入,并且列表的每个元素都会相应地填充,除了BufferedImages。

有没有人有办法解决这个问题?

1 个答案:

答案 0 :(得分:4)

问题可能是ImageIO.read(...)在第一次读取图像后错误地定位了流。

我看到两个选项来解决这个问题:

  • 重写BufferedImage的序列化以写入图像,高度,宽度,颜色模型/颜色空间标识的后备数组,以及重新创建{{1}所需的其他数据}}。这需要一些代码才能正确处理各种图像,因此我现在将跳过这些细节。可能更快,更准确(但可能会发送更多数据)。

  • 继续使用BufferedImage进行序列化,但使用ImageIO缓冲每次写入,并在每个图像前面加上字节数。回读时,首先要读取字节数,并确保完全读取每个图像。这很容易实现,但由于文件格式的限制,某些图像可能会被转换或丢失细节(即JPEG压缩)。类似的东西:

    ByteArrayOutputStream