2012-05-26 8 views
8

Tengo un TouchPoint clase que implementa Serializable y porque contiene Bitmap escribí writeObject y readObject para esa clase:decodeByteArray y copyPixelsToBuffer no funciona. volvió SkImageDecoder :: fábrica nula

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

El problema es que tengo

SkImageDecoder :: La fábrica devolvió nulo

Entonces, ¿cómo puedo solucionarlo? Sé que posible solución es cambiar writeObject() para

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

pero este método es más lento casi 10+ veces.

14ms
  • copyPixelsToBuffer ~ para la escritura de la imagen
  • _bmp.compress ~ 160ms

ACTUALIZACIÓN entero de que el problema real es que después de

buffer.array(); 

Todo byte [] los elementos de la matriz son: 0

+0

¿No recibe ningún otro mensaje de error? Quizás, 'int bytes = _bmp.getRowBytes() * _bmp.getHeight()' resolvería su problema. –

+0

no, no recibo otros mensajes. eso no soluciona el problema Sin embargo, encuentro la manera de resolver esto. Voy a publicar una respuesta más tarde. – Cyberon

Respuesta

7

Finalmente encuentro una manera de hacerlo funcionar y ser más rápido al mismo tiempo. Me encontré con dos problemas con este método:

  1. que debe pasar el parámetro Bitmap.Config también, sin que no pueda decodificar la matriz de bytes
  2. _bmp.compress y _bmp.copyPixelsToBuffer dar diferentes matrices por lo que No se pudo usar decodeByteArray.

les resolvieron este 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; 
    } 
} 

Esto es lo suficientemente rápido para mí - aproximadamente 15x más rápido que la forma bmp.compress. Espero que esto ayude :)

+0

Bueno, parece que es mucho más lento que el método de abajo. ¿Estoy cometiendo algún error? –

1

de mapa de bits a byte []:

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

Use Bufferedstreams para un mejor rendimiento.

+2

Ya he dicho que este método es demasiado lento, porque comprime el mapa de bits, lo que lleva mucho tiempo. Ya encuentro la manera que funciona ~ 15 veces más rápido. – Cyberon

+0

¿También con un bufferstream? – Klaasvaak

+1

desafortunadamente sí :( – Cyberon