2011-05-03 10 views
11

나는 첫 번째 안드로이드 응용 프로그램에서 작업을 시작했으며 여러 레이어가있는 이미지를 처리하는 응용 프로그램의 기초를 가지고 있습니다. PNG 형식으로 프로젝트 파일의 플랫 버전을 내보낼 수 있지만 나중에 편집 할 수 있도록 레이어 된 이미지를 저장할 수 있기를 원합니다 (텍스트 기반 레이어와 같은 특정 레이어에 적용된 옵션 포함).자바에서 android.graphics.Bitmap

어쨌든 파일에 작성해야하는 클래스가 'Serializable'이지만 android.graphics.Bitmap이 직렬화 할 수 없다는 사실로 인해로드 블록이 조금이라도 생기게했습니다. 다음 코드는 기본적으로 Bitmap을 PNG로 ByteArray에 출력하고 다시 'readObject'의 일부로 읽어야합니다. 그러나 코드가 실행될 때 - 내가 읽은 'imageByteArrayLength'변수가 출력되는 변수와 동일한 지 확인할 수 있지만 '비트 맵 이미지'는 항상 null입니다.

도움을 주시면 감사하겠습니다. 읽어 주셔서 감사합니다.

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을 구현하고 원래의 Bitmap에서 PNG 데이터를 저장하는 바이트 []가있는 사용자 지정 개체 (BitmapDataObject)를 제작했습니다. 이를 사용하여 데이터는 올바르게 ObjectOutputStream/ObjectInputStream에 저장됩니다.이 객체는 비트 맵 객체를 사용자 정의 객체의 byte []에 PNG 형식으로 저장하여 직렬화 및 비 직렬화 할 수 있습니다. 아래의 코드는 내 쿼리를 해결합니다.

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

이 코드는 serializable을 올바르게 사용하는 방법을 나타내지 않는다고 생각합니다. –

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

    } 
}