2010-09-02 19 views
7

Sto cercando di serializzare una classe in cui ho una variabile bitmap. Ecco il codice che è un po 'di lavoro .... Ho bisogno di aiuto per scoprire che cosa è ancora sbagliata .....android come salvare un bitmap - codice 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 non sempre un errore, ma la bitmap Im ottenendo sono sbagliato ... inoltre, non so come riconoscere quale flag Bitmap.Config sia adatto ... come sapere?

aiuto?

risposta

13

Ecco il codice per una serializzazione con ottimizzazione della memoria. Sto usando un buffer statico che sta crescendo alla dimensione più grande della bitmap e che riuso ogni volta.

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

Sono un novizio nel mondo Java/Android e ho implementato il codice di esempio per la mia classe. Ha anche alcune proprietà di tipi primitivi e una proprietà di tipo Bitmap. Tuttavia, nel metodo readObject ottengo una OptionalDataException quando provo a leggere la prima proprietà, es. "imageSource = (String) in.readObject();" Non ho idea del perché questo stia accadendo - qualsiasi idea sarebbe molto apprezzata. Grazie ... – codedog

+0

Vedo solo due motivi possibili. Innanzitutto, l'eccezione stessa ti dice: "Segnala che la classe ObjectInputStream ha incontrato un tipo primitivo (int, char, ecc.) Invece di un'istanza dell'oggetto nel flusso di input." – Fabien

+0

Secondo. Potrebbe essere che non stai leggendo i dati nello stesso ordine in cui li hai scritti nell'oggetto serializzato. Stai attento a rispettare l'ordine ... prima scrissi, prima di leggere. – Fabien

4

Non c'è bisogno di avere la matrice ridondante + tutta la logica attorno + utilizzare i metodi riportati di manipolare il buffer + utf è migliore per archi ed evitare il calchi + sincronizzazione (ma non è thread safe comunque):

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

Questo ha funzionato bene per me, tranne per il problema che ho incontrato qui - StackOverflow.com/questions/10442761/.... Qualche idea? – Brad

4

Per semplificare le cose, è possibile utilizzare la serializzazione standard per tutti i campi diversi dalla bitmap. Contrassegna la bitmap come transitoria e usa out.defaultWriteObject(); e in.defaultReadObject() ;. Questo pulisce davvero il codice:

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