当前位置: 首页 > 面试题库 >

序列化包含BufferedImages的对象

吴举
2023-03-14
问题内容

顾名思义,我正在尝试将包含一些BufferedImages(包括其他变量,字符串等)的对象保存到文件中。

我发现了这一点:
如何序列化包含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外,列表中的每个元素均已相应填充。

有谁有办法解决这个问题?


问题答案:

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

我看到两个解决方案:

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

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

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

    }



 类似资料:
  • 问题内容: 我正在尝试用Java创建一个简单的图像编辑程序。我制作了一个对象,其中包含有关正在编辑的图像的所有信息(一些基本属性,所应用的效果列表,层列表等),我想要一种简单的方法将其保存到磁盘,以便稍后再次打开。 我发现使用Java的defualt 接口可能正是我想要的,我可以将整个对象写到文件中,稍后再读回内存中。但是,包括和不能序列化(其他所有方法都可以)。 我知道可以重写和方法,但我从未这

  • 然后是班级选拔: 教材: 因此,我主要创建新用户并将其序列化: 一切都很完美,但如果我这样做: 然后我想序列化对象用户,程序崩溃了。我得到的结果是: JAVA木卫一。NotSerializableException:在java上。木卫一。ObjectOutputStream。java上的WriteObject 0(ObjectOutputStream.java:1183)。木卫一。ObjectOu

  • 问题内容: 我有一个对象(解析树),其中包含子节点,这些子节点是对其他节点的引用。 我想使用序列化此对象,但是我得到了 TypeError:循环对象值 因为我提到的结构。 我该如何解决?对我而言,在序列化对象中是否表示对其他节点的引用并不重要。 另一方面,在创建对象时从对象中删除这些属性似乎很乏味,我也不想对解析器(水仙)进行更改。 问题答案: 使用的第二个参数,该替代品的功能,以排除已序列化对象

  • 问题内容: 你好(对不起我的英语) 我正在开发使用Spring SPRING MVC的json前端网站消耗Web服务的Web服务。spring mvc使用JsonIdentityInfo选项进行序列化,因此每个对象仅在json中写入一次,并且每次都使用引用进行写入,例如她使用相同的对象“ component”有2个“ computer”,因此spring将ID设置为第一个组件(“ @compone

  • 我试图调用一个restendpoint,它返回一个pojo对象,如下所示: 以下是电话: 问题是我已经尝试了一些方法,例如忽略 OffsetDateTime 属性或尝试更改该日期的格式,但它会引发此错误: 否则它将返回空:(解决这个问题的好解决方案是什么?

  • 我正在使用Jackson 2.4将对象序列化为JSON。 当我序列化对象列表时,如果某些元素为空,则结果字符串包含一些“空”字符串。 如何防止元素被序列化?是否有任何配置?我已经设置了! 下面是我的代码: 连载之后我得到了这个: