2010-09-02 6 views
7

Im essayant de sérialiser une classe dans laquelle j'ai une variable bitmap. Voici le code qui est un peu de travail .... je besoin d'aide pour savoir ce qui est encore mal .....android comment enregistrer un bitmap - code buggy

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

} 

Im ne reçoit pas une erreur mais le bitmap Im se sont mal ... aussi, je ne sais pas comment savoir quel drapeau Bitmap.Config est approprié ... comment savoir?

toute aide?

Répondre

13

Voici le code d'une sérialisation avec optimisation de la mémoire. Im en utilisant un tampon statique qui grandit à la plus grande taille de bitmap et que je réutilise chaque fois.

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

Je suis un débutant dans le monde de Java/Android et j'ai mis en place votre exemple de code pour ma classe. Il possède également des propriétés de types primitifs et une propriété de type Bitmap. Cependant, dans la méthode readObject, j'obtiens une exception OptionalDataException lorsque j'essaie de lire la première propriété, c'est-à-dire. "imageSource = (Chaîne) in.readObject();" Je ne sais pas pourquoi cela se passe - toutes les idées seraient grandement appréciées. Merci ... – codedog

+0

Je ne vois que deux raisons possibles. Tout d'abord, l'Exception elle-même vous dit: "Signale que la classe ObjectInputStream a rencontré un type primitif (int, char etc.) au lieu d'une instance d'objet dans le flux d'entrée." – Fabien

+0

Deuxième. Peut-être ne lisez-vous pas les données dans le même ordre que vous les avez écrites dans l'objet sérialisé. Attention à respecter l'ordre ... d'abord écrit, d'abord à lire. – Fabien

4

Pas besoin d'avoir le réseau redondant + toute la logique autour de + utiliser les méthodes données pour manipuler le tampon + utf vaut mieux pour les chaînes et éviter les moulages + synchronisation (mais pas thread sûr de toute façon):

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

Cela a bien fonctionné pour moi, sauf pour le problème que j'ai rencontré ici - stackoverflow.com/questions/10442761/.... Des idées? – Brad

4

Pour simplifier les choses, vous pouvez utiliser la sérialisation standard pour tous les champs autres que le bitmap. Marquez simplement le bitmap comme transitoire, et utilisez out.defaultWriteObject(); et in.defaultReadObject() ;. Cela nettoie vraiment le code:

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