序列化一个包含 BufferedImages 的 object
Serializing an object that includes BufferedImages
如标题所示,我正在尝试将 object 保存到文件中,其中包含(在其他变量、字符串等中)一些 BufferedImages。
我发现了这个:
How to serialize an object that includes BufferedImages
它就像一个魅力,但有一个小挫折:如果你的 object 只包含一张图片,它会很好用。
我一直在努力让他的解决方案可以处理多个图像(理论上应该可以),但每次我读入文件时,我都会 object 回来,我得到图像数量正确,但实际上只有第一张图像被读入;其他的只是其中没有数据的空图像。
这是我的 object 的样子:
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));
}
}
}
这就是我在文件中写入和读取 object 的方式:
// 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();}
即使我有一个 object 的列表,它们也会被正确读取,并且列表中的每个元素都会相应地填充,BufferedImages 除外。
有人有办法解决这个问题吗?
问题很可能是 ImageIO.read(...)
在读取第一张图像后错误地定位了流。
我看到两个选项可以解决这个问题:
重写 BufferedImage
s 的序列化以写入图像、高度、宽度、颜色 model/color space 标识符的支持数组,以及重建 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)));
}
}
如标题所示,我正在尝试将 object 保存到文件中,其中包含(在其他变量、字符串等中)一些 BufferedImages。
我发现了这个: How to serialize an object that includes BufferedImages
它就像一个魅力,但有一个小挫折:如果你的 object 只包含一张图片,它会很好用。
我一直在努力让他的解决方案可以处理多个图像(理论上应该可以),但每次我读入文件时,我都会 object 回来,我得到图像数量正确,但实际上只有第一张图像被读入;其他的只是其中没有数据的空图像。
这是我的 object 的样子:
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));
}
}
}
这就是我在文件中写入和读取 object 的方式:
// 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();}
即使我有一个 object 的列表,它们也会被正确读取,并且列表中的每个元素都会相应地填充,BufferedImages 除外。
有人有办法解决这个问题吗?
问题很可能是 ImageIO.read(...)
在读取第一张图像后错误地定位了流。
我看到两个选项可以解决这个问题:
重写
BufferedImage
s 的序列化以写入图像、高度、宽度、颜色 model/color space 标识符的支持数组,以及重建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))); } }