Serializing and De-Serializing android.graphics.Bitmap in Java
It took a while, but I have found a clean solution to this problem. I produced a custom object (BitmapDataObject) that implements Serializable and has a byte[] to store the PNG data from the original Bitmap. Using this, the data is stored correctly in the ObjectOutputStream / ObjectInputStream - which effectively allows one to Serialize and Deserialize a Bitmap object by storing it as a PNG in a byte[] in a custom object. The code below resolves my query.
private String title;
private int sourceWidth, currentWidth;
private int sourceHeight, currentHeight;
private Bitmap sourceImage;
private Canvas sourceCanvas;
private Bitmap currentImage;
private Canvas currentCanvas;
private Paint currentPaint;
protected class BitmapDataObject implements Serializable {
private static final long serialVersionUID = 111696345129311948L;
public byte[] imageByteArray;
}
/** Included for serialization - write this layer to the output stream. */
private void writeObject(ObjectOutputStream out) throws IOException{
out.writeObject(title);
out.writeInt(currentWidth);
out.writeInt(currentHeight);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
currentImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
BitmapDataObject bitmapDataObject = new BitmapDataObject();
bitmapDataObject.imageByteArray = stream.toByteArray();
out.writeObject(bitmapDataObject);
}
/** Included for serialization - read this object from the supplied input stream. */
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
title = (String)in.readObject();
sourceWidth = currentWidth = in.readInt();
sourceHeight = currentHeight = in.readInt();
BitmapDataObject bitmapDataObject = (BitmapDataObject)in.readObject();
Bitmap image = BitmapFactory.decodeByteArray(bitmapDataObject.imageByteArray, 0, bitmapDataObject.imageByteArray.length);
sourceImage = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888);
currentImage = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888);
sourceCanvas = new Canvas(sourceImage);
currentCanvas = new Canvas(currentImage);
currentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
thumbnailPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
thumbnailPaint.setARGB(255, 200, 200, 200);
thumbnailPaint.setStyle(Paint.Style.FILL);
}
Here is an example of a serializable object that can wrap bitmaps.
public class BitmapDataObject implements Serializable {
private Bitmap currentImage;
public BitmapDataObject(Bitmap bitmap)
{
currentImage = bitmap;
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
currentImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
out.writeInt(byteArray.length);
out.write(byteArray);
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
int bufferLength = in.readInt();
byte[] byteArray = new byte[bufferLength];
int pos = 0;
do {
int read = in.read(byteArray, pos, bufferLength - pos);
if (read != -1) {
pos += read;
} else {
break;
}
} while (pos < bufferLength);
currentImage = BitmapFactory.decodeByteArray(byteArray, 0, bufferLength);
}
}