2012-05-26 8 views
8

Ho un TouchPoint classe che implementa Serializable e perché contiene Bitmap ho scritto writeObject e readObject per quella classe:decodeByteArray e copyPixelsToBuffer non funzionano. SkImageDecoder :: Fabbrica restituito nulla

private void writeObject(ObjectOutputStream oos) throws IOException { 
    long t1 = System.currentTimeMillis(); 
    oos.defaultWriteObject(); 
    if(_bmp!=null){ 
     int bytes = _bmp.getWidth()*_bmp.getHeight()*4; 

     ByteBuffer buffer = ByteBuffer.allocate(bytes); 
     _bmp.copyPixelsToBuffer(buffer); 

     byte[] array = buffer.array();  

     oos.writeObject(array); 

    } 
    Log.v("PaintFX","Elapsed Time: "+(System.currentTimeMillis()-t1)); 
} 

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{ 
    ois.defaultReadObject(); 
    byte[] data = (byte[]) ois.readObject(); 
    if(data != null && data.length > 0){ 
     _bmp = BitmapFactory.decodeByteArray(data, 0, data.length); 
    } 
} 

Il problema è che ottengo

SkImageDecoder :: Fabbrica restituita null

Quindi, come posso risolvere il problema. So che possibile soluzione è quella di cambiare writeObject() per

ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 
_bmp.compress(Bitmap.CompressFormat.PNG, 100, byteStream); 
oos.writeObject(byteStream.toByteArray); 

ma questo metodo è più lento di quasi 10+ volte.

  • copyPixelsToBuffer ~ 14ms per la scrittura di un'immagine
  • _bmp.compress ~ 160ms

UPDATE scoprire che il vero problema è che dopo

buffer.array(); 

Tutti byte [] gli elementi dell'array sono: 0

+0

Non ricevi altri messaggi di errore? Forse, 'int bytes = _bmp.getRowBytes() * _bmp.getHeight()' risolverebbe il tuo problema. –

+0

no, non ricevo altri messaggi. questo non ha risolto il problema. Tuttavia, trovo il modo di risolverlo. Pubblicherò una risposta più tardi. – Cyberon

risposta

7

Finalmente trovo un modo per farlo funzionare ed essere più veloce allo stesso tempo. Sono stato incontrato due problemi con questo metodo:

  1. I dovrebbe passare il parametro Bitmap.Config anche senza che non riesco a decodificare il byte
  2. _bmp.compress e _bmp.copyPixelsToBuffer dare matrici differenti così impossibile usare decodeByteArray.

ho risolto loro in questo modo

private void writeObject(ObjectOutputStream oos) throws IOException { 
    oos.defaultWriteObject(); 

    if(_bmp!=null){ 
     int bytes = _bmp.getWidth()*_bmp.getHeight()*4; 

     ByteBuffer buffer = ByteBuffer.allocate(bytes); 
     _bmp.copyPixelsToBuffer(buffer); 

     byte[] array = new byte[bytes]; // looks like this is extraneous memory allocation 

     if (buffer.hasArray()) { 
      try{ 
       array = buffer.array(); 
      } catch (BufferUnderflowException e) { 
       e.printStackTrace(); 
      } 
     } 

     String configName = _bmp.getConfig().name(); 

     oos.writeObject(array); 
     oos.writeInt(_bmp.getWidth()); 
     oos.writeInt(_bmp.getHeight()); 
     oos.writeObject(configName); 
    } else { 
     oos.writeObject(null); 
    } 
} 

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{ 
    ois.defaultReadObject(); 

    byte[] data = (byte[]) ois.readObject(); 
    if (data != null) { 
     int w = ois.readInt(); 
     int h = ois.readInt(); 
     String configName = (String) ois.readObject(); 

     Bitmap.Config configBmp = Bitmap.Config.valueOf(configName); 
     Bitmap bitmap_tmp = Bitmap.createBitmap(w, h, configBmp); 
     ByteBuffer buffer = ByteBuffer.wrap(data); 

     bitmap_tmp.copyPixelsFromBuffer(buffer); 

     _bmp = bitmap_tmp.copy(configBmp,true); 

     bitmap_tmp.recycle(); 
    } else { 
     _bmp = null; 
    } 
} 

Questo è abbastanza veloce per me - a circa 15x più veloce allora il modo bmp.compress. spero che questo aiuti :)

+0

beh sembra che sia molto più lento del metodo qui sotto. Sto facendo un errore? –

1

Bitmap per byte []:

Bitmap bmp; // your bitmap 
ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); 
byte[] byteArray = stream.toByteArray(); 

Utilizzare Bufferedstreams per migliorare le prestazioni.

+2

Ho già detto che questo metodo è troppo lento, perché comprime la Bitmap che impiega molto tempo. Ho già trovato il modo in cui funziona ~ 15 volte più veloce. – Cyberon

+0

Anche con un bufferedstream? – Klaasvaak

+1

sfortunatamente sì :( – Cyberon