Serializing an object that includes BufferedImages

前端 未结 1 1274
野的像风
野的像风 2021-01-07 12:18

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

I found this: How to serialize

相关标签:
1条回答
  • 2021-01-07 13:03

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

    I see two options to fix this:

    • 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).

    • 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)));
          }
      }
      
    0 讨论(0)
提交回复
热议问题