before explaining my thing i want to mention that i haven't tried-search any alternate solutions (which i am pretty confident something will be found). I am just pretty curious to know why this is happening.
So...I have an object that has 2 transient buffered images fields (firstimage and second image like the following example).
Since bufferedimage does not implement serializable, one way to serialize them (i found in SO) is this. I did the exact same thing and everything worked perfect for the first image. (being saved successfully, being loaded fine aswell).
However, about the second image there is a problem which i can't explain. I serialize my object without any problems but when i try to load it, the second image is being read as null for some reason. Is there anything i am missing to my code?
I show my problem with a quick swing application.
- load1 button will load the first image and set it to the object.
- load2 button does the same thing for the second image
- Save button serializes the object and saves it locally
- Show button will show if any image is null
So, i start the app. Click load1 & load2. Click save. Click show = none of them is null. Close the app.
I start the app again and it loads the object on start. I click show and image1 is NOT null, but image 2 is null.
Why is this happening? what can i do in order to make this way work? What alternate solution would you suggest?
p.s: I would like to avoid getting images to a base64 or to byte[] and serialize them.
Person class (name makes no sense i just had it from previous testing):
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import javax.imageio.ImageIO;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private transient BufferedImage firstImage;
private transient BufferedImage secondImage;
public Person() {
}
private void writeObject(ObjectOutputStream out) {
try {
out.defaultWriteObject();
if (firstImage != null)
{
ImageIO.write(firstImage, "png", out);
System.out.println("First image saved.");
}
if (secondImage != null) {
ImageIO.write(secondImage, "png", out);
System.out.println("Second image saved.");
}
System.out.println("-------------------------");
} catch (IOException e) {
e.printStackTrace();
}
}
private void readObject(ObjectInputStream in) {
try {
in.defaultReadObject();
firstImage = ImageIO.read(in);
secondImage = ImageIO.read(in);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Person loadPerson() {
String path = "C://Users//George//Desktop//person.tmp";
File file = new File(path);
Person p = new Person();
if (!file.exists())
return p;
try (FileInputStream fis = new FileInputStream(path); ObjectInputStream ois = new ObjectInputStream(fis);) {
p = (Person) ois.readObject();
ois.close();
fis.close();
} catch (IOException | ClassNotFoundException e1) {
e1.printStackTrace();
}
return p;
}
public void savePerson() {
String path = "C://Users//George//Desktop//person.tmp";
try (FileOutputStream fos = new FileOutputStream(path); ObjectOutputStream oos = new ObjectOutputStream(fos);) {
oos.writeObject(this);
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public BufferedImage getSecondImage() {
return secondImage;
}
public void setSecondImage(BufferedImage secondImage) {
this.secondImage = secondImage;
}
public BufferedImage getFirstImage() {
return firstImage;
}
public void setFirstImage(BufferedImage firstImage) {
this.firstImage = firstImage;
}
}
The app:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UnsupportedLookAndFeelException;
@SuppressWarnings("serial")
public class Test extends JPanel {
private JFrame f;
private Person person;
public Test() {
JButton load1 = new JButton("load img1");
load1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
BufferedImage tmp = ImageIO.read(new File("C://Users//George//Desktop//pencil.png"));
person.setFirstImage(tmp);
tmp.flush();
tmp = null;
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
add(load1);
JButton load2 = new JButton("load img2");
load2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
BufferedImage tmp = ImageIO.read(new File("C://Users//George//Desktop//map.png"));
person.setSecondImage(tmp);
tmp.flush();
tmp = null;
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
add(load2);
JButton save = new JButton("save");
save.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
person.savePerson();
}
});
add(save);
JButton show = new JButton("show which is null");
show.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (person.getFirstImage() == null)
System.out.println("first image null");
else
System.out.println("first image not null");
if (person.getSecondImage() == null)
System.out.println("second image null");
else
System.out.println("second image not null");
System.out.println("---------------------");
}
});
add(show);
}
private void display() {
person = Person.loadPerson();
f = new JFrame("Buffered images");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.setSize(new Dimension(300, 300));
// f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException,
IllegalAccessException, UnsupportedLookAndFeelException {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Test().display();
}
});
}
}