Bitmapをバイト配列としてserializeする方法
例えばBitmapのデータをSQLiteのデータベースに保存したい場合、BLOB型としてバイトデータをそのまま保存することが考えられます。
cursorとやり取りするときのフィールド定義は↓こんな感じのバイト型の配列になると思います。
private byte[] icon_bitmap;
オブジェクトをバイト配列に変換するには、ファイルを使わない場合ByteArrayOutputStream を使うと出来ます。
こちらのサイト様を参考にさせていただきました。
JAVAでオブジェクト(Class)をバイト配列に変換する方法 - 異邦人になってみた〜上海の人
ByteArrayOutputStream byteos = new ByteArrayOutputStream(); ObjectOutputStream objos = new ObjectOutputStream(byteos); objos.writeObject(ここにBitmapオブジェクトを入れる); //以下省略
ですが、上記のようにBitmapを変換しようとするとjava.io.NotSerializableExceptionが発生してしまいます。
BitmapクラスがSerializableを実装していないからなのですが、こうした場合Serializableを実装したクラス内でBitmapオブジェクトを保持すれば変換することが出来ます。
こちら↓のページを参考にしました。
serializable - How to fix a java.io.NotSerializableException: android.graphics.Bitmap - Stack Overflow
以上をコードで書きますと次のような感じです。
Bitmapをバイト配列に変換してDB保存→DBから取り出したバイト配列をBitmapに戻す処理を念頭に書いております。
まず、Serializableをimplementsしたクラスを作成します。(追記:こちらのクラスは↑の参考サイトのクラスそのままです。適宜編集して下さい。この記事ではクラス内のwriteObject、readObjectメソッドは使ってません。)
CachedBitmap.java
public class CachedBitmap implements Serializable { private static final long serialVersionUID = -6298516694275121291L; public Bitmap getBitmap() { return bitmap; } transient Bitmap bitmap; public CachedBitmap(){}; public CachedBitmap(Bitmap b){ bitmap = b; } private void writeObject(ObjectOutputStream oos) throws IOException{ oos.defaultWriteObject(); if(bitmap!=null){ ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); boolean success = bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream); if(success){ oos.writeObject(byteStream.toByteArray()); } } } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{ ois.defaultReadObject(); byte[] image = (byte[]) ois.readObject(); if(image != null && image.length > 0){ bitmap = BitmapFactory.decodeByteArray(image, 0, image.length); } } }
このクラスをバイト配列に変換する時に使います
/** * Bitmapオブジェクトをbyte配列に変換 * @param bitmap * @return * @throws IOException */ public static byte[] getByteObject(final Bitmap bitmap) throws IOException { ByteArrayOutputStream byteos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteos); CachedBitmap cachedBitmap = new CachedBitmap(bitmap); out.writeObject(cachedBitmap); return byteos.toByteArray(); }
このメソッドの戻り値をDBに保存します。
DBから取り出したバイト配列をBitmapオブジェクトに変換するには、やはり先程のCachedBitmapクラスを使います。
/** * byte配列をBitmapオブジェクトに変換 * @param objByte * @return * @throws IOException * @throws ClassNotFoundException */ public static Bitmap getBitmapObject(final byte[] objByte) throws IOException, ClassNotFoundException { ByteArrayInputStream byteis = new ByteArrayInputStream(objByte); ObjectInputStream in = new ObjectInputStream(byteis); CachedBitmap cachedBitmap = (CachedBitmap) in.readObject(); return cachedBitmap.getBitmap(); }
以上です。