序列化包含BufferedImages的对象 [英] Serializing an object that includes BufferedImages

查看:144
本文介绍了序列化包含BufferedImages的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As the title suggests, I'm trying to save to file an object that contains (among other variables, Strings, etc) a few BufferedImages.

这:
如何序列化该对象包括BufferedImages

它的工作原理很吸引人,但有一点挫折:如果您的对象仅包含一个图像,效果很好。

And it works like a charm, but with a small setback: it works well if your object contains only ONE image.

我一直在努力让他的解决方案可以处理多个图像(理论上应该可以使用),但是每次我读入文件时,我都会得到我的对象,正确数量的图像,但实际上只读取了第一张图像;

I've been struggling to get his solution to work with more than one image (which in theory should work) but each time I read the file in, I get my object back, I get the correct number of images, but only the first image actually gets read in; the others are just null images that have no data in them.

这就是我的对象的样子:

This is how my object looks like:

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

    }

这是我如何在文件中读写对象:

This is how I'm writing and reading the object to and from a file:

// 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之外。

Even though I have a list of objects, they get read in correctly and each element of the list is populated accordingly, except for the BufferedImages.

有人可以解决此问题吗?

Does anyone have any means of fixing this?

推荐答案

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

The problem is likely that ImageIO.read(...) incorrectly positions the stream after the first image read.

我看到两个解决方案:


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

  • Rewrite the serialization of the BufferedImages to write the backing array(s) of the image, height, width, color model/color space identifer, and other data required to recreate the BufferedImage. This requires a bit of code to correctly handle all kinds of images, so I'll skip the details for now. Might be faster and more accurate (but might send more data).

继续使用 ImageIO 进行序列化,但使用 ByteArrayOutputStream 缓冲每次写操作,并在每个图像之前添加其字节数。回读时,首先读取字节数,并确保完全读取每个图像。这实现起来很简单,但是由于文件格式的限制,某些图像可能会转换或丢失细节(即JPEG压缩)。像这样的东西:

Continue to serialize using ImageIO, but buffer each write using a ByteArrayOutputStream, and prepend each image with its byte count. When reading back, start by reading the byte count, and make sure you fully read each image. This is trivial to implement, but some images might get converted or lose details (ie. JPEG compression), due to file format constraints. Something like:

private void writeObject(ObjectOutputStream out) throws IOException {
    out.defaultWriteObject();
    out.writeInt(imageSelection.size()); // how many images are serialized?

    for (BufferedImage eachImage : imageSelection) {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        ImageIO.write(eachImage, "jpg", buffer);

        out.writeInt(buffer.size()); // Prepend image with byte count
        buffer.writeTo(out);         // Write image
    }
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject();

    int imageCount = in.readInt();
    imageSelection = new ArrayList<BufferedImage>(imageCount);
    for (int i = 0; i < imageCount; i++) {
        int size = in.readInt(); // Read byte count

        byte[] buffer = new byte[size];
        in.readFully(buffer); // Make sure you read all bytes of the image

        imageSelection.add(ImageIO.read(new ByteArrayInputStream(buffer)));
    }
}


这篇关于序列化包含BufferedImages的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆