2011-05-03 40 views
11

我已經開始研究我的第一個android應用程序,並具有處理具有多個圖層的圖像的應用程序的基礎。我能夠將平面版本的項目文件導出爲PNG,但我希望能夠保存分層圖像以供日後編輯(包括應用於某些圖層的任何選項,例如基於文本的圖層)。序列化和反序列化Java中的android.graphics.Bitmap

無論如何,我已經確保需要寫入文件的類是'可序列化的',但是由於android.graphics.Bitmap不可序列化的事實而導致了一小塊路由塊。下面的代碼實際上是將位圖作爲PNG輸出到ByteArray中,並應該將其作爲'readObject'的一部分讀入。但是,當代碼運行時 - 我可以驗證讀入的'imageByteArrayLength'變量與輸出的相同 - 但'位圖圖像'始終爲空。

任何幫助將不勝感激。謝謝閱讀。

private String title; 
private int width; 
private int height; 
private Bitmap sourceImage; 
private Canvas sourceCanvas;   
private Bitmap currentImage; 
private Canvas currentCanvas; 
private Paint currentPaint; 

private void writeObject(ObjectOutputStream out) throws IOException{ 
    out.writeObject(title); 
    out.writeInt(width); 
    out.writeInt(height); 

    ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    currentImage.compress(Bitmap.CompressFormat.PNG, 100, stream); 
    byte[] imageByteArray = stream.toByteArray(); 

    int length = imageByteArray.length; 
    out.writeInt(length); 
    out.write(imageByteArray);   
} 

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{ 
    this.title = (String)in.readObject(); 
    this.width = in.readInt(); 
    this.height = in.readInt(); 

    int imageByteArrayLength = in.readInt(); 
    byte[] imageByteArray = new byte[imageByteArrayLength]; 
    in.read(imageByteArray, 0, imageByteArrayLength); 

    BitmapFactory.Options opt = new BitmapFactory.Options(); 
    opt.inPreferredConfig = Bitmap.Config.ARGB_8888; 

    Bitmap image = BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArrayLength, opt); 

    sourceImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
    currentImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 

    sourceCanvas = new Canvas(sourceImage); 
    currentCanvas = new Canvas(currentImage); 
    currentPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 

    if (image != null) { 
     sourceCanvas.drawBitmap(image, 0, 0, currentPaint); 
    } 
} 

回答

25

這花了一段時間,但我找到了一個乾淨的解決方案來解決這個問題。我生成了一個實現Serializable的自定義對象(BitmapDataObject),並有一個byte []來存儲原始位圖中的PNG數據。使用這種方式,數據被正確地存儲在ObjectOutputStream/ObjectInputStream中 - 這有效地允許將一個Bitmap對象序列化和反序列化,方法是將其作爲PNG存儲在自定義對象的byte []中。下面的代碼解決了我的查詢。

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); 
} 
+1

我不認爲這段代碼表示如何正確使用序列化。 – 2016-02-05 22:51:13

2

下面是一個可封裝位圖的可序列化對象的示例。

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); 

    } 
}