2010-09-02 12 views
7

Im intentando serializar una clase en la que tengo una variable de mapa de bits. Aquí está el código que es un poco de trabajo .... Necesito ayuda para averiguar lo que sigue siendo incorrecto .....android cómo guardar un mapa de bits - código de error

private Bitmap myVideoScreenshotBm; 

private void writeObject(ObjectOutputStream out) throws IOException{ 

    out.writeInt(myVideoScreenshotBm.getRowBytes()); 
    out.writeInt(myVideoScreenshotBm.getHeight()); 
    out.writeInt(myVideoScreenshotBm.getWidth()); 

    int bmSize = myVideoScreenshotBm.getHeight() * myVideoScreenshotBm.getRowBytes(); 
    ByteBuffer dst= ByteBuffer.allocate(bmSize); 

    myVideoScreenshotBm.copyPixelsToBuffer(dst); 

    byte[] bytesar=new byte[bmSize]; 
    dst.position(0); 
    dst.get(bytesar); 

    out.write(bytesar); 


} 

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{ 

    int nbRowBytes=in.readInt(); 
    int height=in.readInt(); 
    int width=in.readInt(); 
    // 
    int bmSize = nbRowBytes * height; 
    byte[] toread= new byte[bmSize]; 

    in.read(toread, 0, toread.length); 
    ByteBuffer dst= ByteBuffer.allocate(bmSize); 
    dst.put(toread); 
    dst.position(0); 
    myVideoScreenshotBm=Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8); 
    myVideoScreenshotBm.copyPixelsFromBuffer(dst); 

} 

no estoy recibiendo un error, pero el mapa de bits Im que consigue son mal ... Además, no sé cómo saber qué indicador de Bitmap.Config es adecuado ... ¿cómo saberlo?

¿Alguna ayuda?

Respuesta

13

Aquí está el código para una serialización con optimización de memoria. Estoy usando un búfer estático que está creciendo hasta el tamaño de mapa de bits más grande y que reutilizo cada vez.

public class Video implements Serializable{ 
public long videoId; 
public String title; 
public String publisher; 
public String language; 
public Date lastModified; 
public Date published; 
public String imageUrl; 
public String url; 
public Bitmap myVideoScreenshotBm; 
public Date expireTime; 
//public Drawable myVideoScreenshotDrawable; 

private static ByteBuffer dst; 
private static byte[] bytesar; 

public Video (long newVideoId) { 
    this.videoId=newVideoId; 
} 
private void writeObject(ObjectOutputStream out) throws IOException{ 

    out.writeLong(videoId); 

    out.writeObject(title); 
    out.writeObject(publisher); 
    out.writeObject(language); 
    out.writeObject(lastModified); 
    out.writeObject(published); 
    out.writeObject(expireTime); 

    out.writeObject(imageUrl); 
    out.writeObject(url); 


    out.writeInt(myVideoScreenshotBm.getRowBytes()); 
    out.writeInt(myVideoScreenshotBm.getHeight()); 
    out.writeInt(myVideoScreenshotBm.getWidth()); 

    int bmSize = myVideoScreenshotBm.getRowBytes() * myVideoScreenshotBm.getHeight(); 
    if(dst==null || bmSize > dst.capacity()) 
     dst= ByteBuffer.allocate(bmSize); 

    out.writeInt(dst.capacity()); 

    dst.position(0); 

    myVideoScreenshotBm.copyPixelsToBuffer(dst); 
    if(bytesar==null || bmSize > bytesar.length) 
     bytesar=new byte[bmSize]; 

    dst.position(0); 
    dst.get(bytesar); 


    out.write(bytesar, 0, bytesar.length); 

} 

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{ 

    videoId=in.readLong(); 

    title=(String) in.readObject(); 
    publisher=(String) in.readObject(); 
    language=(String) in.readObject(); 
    lastModified=(Date) in.readObject(); 
    published=(Date) in.readObject(); 
    expireTime=(Date) in.readObject(); 

    imageUrl = (String) in.readObject(); 
    url = (String) in.readObject(); 


    int nbRowBytes=in.readInt(); 
    int height=in.readInt(); 
    int width=in.readInt(); 

    int bmSize=in.readInt(); 



    if(bytesar==null || bmSize > bytesar.length) 
     bytesar= new byte[bmSize]; 


    int offset=0; 

    while(in.available()>0){ 
     offset=offset + in.read(bytesar, offset, in.available()); 
    } 


    if(dst==null || bmSize > dst.capacity()) 
     dst= ByteBuffer.allocate(bmSize); 
    dst.position(0); 
    dst.put(bytesar); 
    dst.position(0); 
    myVideoScreenshotBm=Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); 
    myVideoScreenshotBm.copyPixelsFromBuffer(dst); 
    //in.close(); 
} 

}

+0

Soy un novato en el mundo de Java/Android y he implementado el código de muestra para mi clase. También tiene algunas propiedades de tipos primitivos y una propiedad de tipo Bitmap. Sin embargo, en el método readObject obtengo una OptionalDataException cuando intento leer la primera propiedad, es decir. "imageSource = (String) in.readObject();" No tengo idea de por qué sucede esto, cualquier idea sería muy apreciada. Gracias ... – codedog

+0

Solo veo dos razones posibles. En primer lugar, la Excepción misma le dice: "Señala que la clase ObjectInputStream encontró un tipo primitivo (int, char, etc.) en lugar de una instancia de objeto en la corriente de entrada". – Fabien

+0

Segundo. Puede ser que no esté leyendo los datos en el mismo orden en que los escribió en el objeto serializado. Tenga cuidado de respetar el orden ... primero escribió, primero para ser leído. – Fabien

4

No hay necesidad de tener la matriz redundante + toda la lógica alrededor de + usar los métodos dados para manipular la memoria intermedia + UTF es mejor para cuerdas y evitar los elencos + sincronización (pero no es hilo seguro de todos modos):

private synchronized void writeObject(final ObjectOutputStream out) throws IOException { 
    out.writeUTF(title); 
    out.writeUTF(url_friendly_name); 
    out.writeUTF(creator_name); 
    out.writeUTF(version); 
    out.writeUTF(package_name); 
    out.writeUTF(contact_website); 
    out.writeInt(popularity); 
    out.writeUTF(inconditional_redirect == null ? "" : inconditional_redirect); 
    out.writeUTF(custom_description == null ? "" : custom_description); 

    out.writeInt(icon.getRowBytes()); 
    out.writeInt(icon.getHeight()); 
    out.writeInt(icon.getWidth()); 
    out.writeInt(icon.getConfig().ordinal()); 

    final int bmSize = icon.getRowBytes() * icon.getHeight(); 
    if (dst == null || bmSize > dst.capacity()) { 
     dst = ByteBuffer.allocate(bmSize); 
    } 
    dst.rewind(); 
    icon.copyPixelsToBuffer(dst); 
    dst.flip(); 
    out.write(dst.array(), 0, bmSize); 
} 


private synchronized void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { 
    title = in.readUTF(); 
    url_friendly_name = in.readUTF(); 
    creator_name = in.readUTF(); 
    version = in.readUTF(); 
    package_name = in.readUTF(); 
    contact_website = in.readUTF(); 
    popularity = in.readInt(); 
    inconditional_redirect = in.readUTF(); 
    custom_description = in.readUTF(); 

    final int nbRowBytes = in.readInt(); 
    final int height = in.readInt(); 
    final int width = in.readInt(); 
    final Bitmap.Config config = Bitmap.Config.values()[in.readInt()]; 

    final int bmSize = nbRowBytes * height; 
    if (dst == null || bmSize > dst.capacity()) { 
     dst = ByteBuffer.allocate(bmSize); 
    } 
    dst.rewind(); 
    in.read(dst.array(), 0, bmSize); 

    icon = Bitmap.createBitmap(width, height, config); 
    icon.copyPixelsFromBuffer(dst); 
} 
+0

Esto funcionó bien para mí, excepto por el problema que encontré aquí: stackoverflow.com/questions/10442761/.... ¿Algunas ideas? – Brad

4

Para simplificar las cosas, puede utilizar la serialización estándar para todos los campos que no sean el mapa de bits. Simplemente marque el mapa de bits como transitorio y use out.defaultWriteObject(); y in.defaultReadObject() ;. Esto realmente limpia el código:

private String title; 
private String description; 
private transient Bitmap icon; 

private synchronized void writeObject(final ObjectOutputStream out) 
    throws IOException { 
    // Serialize everything but the image 
    out.defaultWriteObject(); 

    // Now serialize the image 
    out.writeInt(icon.getRowBytes()); 
    out.writeInt(icon.getHeight()); 
    out.writeInt(icon.getWidth()); 
    out.writeInt(icon.getConfig().ordinal()); 

    final int bmSize = icon.getRowBytes() * icon.getHeight(); 
    if (dst == null || bmSize > dst.capacity()) { 
    dst = ByteBuffer.allocate(bmSize); 
    } 
    dst.rewind(); 
    icon.copyPixelsToBuffer(dst); 
    dst.flip(); 
    out.write(dst.array(), 0, bmSize); 
} 

private void readObject(ObjectInputStream in) throws IOException, 
    ClassNotFoundException { 
    // Read everything but the image 
    in.defaultReadObject(); 

    // Now read the image 
    final int nbRowBytes = in.readInt(); 
    final int height = in.readInt(); 
    final int width = in.readInt(); 
    final Bitmap.Config config = Bitmap.Config.values()[in.readInt()]; 

    final int bmSize = nbRowBytes * height; 
    if (dst == null || bmSize > dst.capacity()) { 
    dst = ByteBuffer.allocate(bmSize); 
    } 
    dst.rewind(); 
    in.read(dst.array(), 0, bmSize); 

    icon = Bitmap.createBitmap(width, height, config); 
    icon.copyPixelsFromBuffer(dst); 
} 
Cuestiones relacionadas