Convertir la matriz de bytes de 4 bits en escala de grises a Bitmap Android

Estoy recuperando una imagen en bruto de una cámara y las especificaciones de la imagen son los siguientes:

  • Resolución de 80 x 60
  • Escala de grises de 4 bits

Recupero la imagen como una matriz de bytes y tienen una matriz que es 2400 (1/2 * 80 * 60) bytes de largo. El siguiente paso es convertir la matriz de bytes en un mapa de bits. Ya he usado el

BitmapFactory.decodeByteArray(bytes, 0, bytes.length) 

Pero que no devolvió una imagen visualizable. Miré este poste y copié el código abajo en mi uso de Androide, pero conseguí un "amortiguador no bastante grande para los pixeles" error del tiempo de ejecución.

 byte [] Src; //Comes from somewhere... byte [] Bits = new byte[Src.length*4]; //That's where the RGBA array goes. int i; for(i=0;i<Src.length;i++) { Bits[i*4] = Bits[i*4+1] = Bits[i*4+2] = ~Src[i]; //Invert the source bits Bits[i*4+3] = -1;//0xff, that's the alpha. } //Now put these nice RGBA pixels into a Bitmap object Bitmap bm = Bitmap.createBitmap(Width, Height, Bitmap.Config.ARGB_8888); bm.copyPixelsFromBuffer(ByteBuffer.wrap(Bits)); 

En la parte inferior del hilo, el cartel original tenía el mismo error que tengo actualmente. Sin embargo, su problema fue corregido con el código pegado arriba. ¿Alguien tiene alguna sugerencia sobre cómo convertir la imagen en bruto o la matriz RGBA en un mapa de bits?

¡Muchas gracias!

ACTUALIZAR:

He seguido la sugerencia de Geobits y este es mi nuevo código

 byte[] seperatedBytes = new byte[jpegBytes.length * 8]; for (int i = 0; i < jpegBytes.length; i++) { seperatedBytes[i * 8] = seperatedBytes[i * 8 + 1] = seperatedBytes[i * 8 + 2] = (byte) ((jpegBytes[i] >> 4) & (byte) 0x0F); seperatedBytes[i * 8 + 4] = seperatedBytes[i * 8 + 5] = seperatedBytes[i * 8 + 6] = (byte) (jpegBytes[i] & 0x0F); seperatedBytes[i * 8 + 3] = seperatedBytes[i * 8 + 7] = -1; //0xFF } 

Ahora, puedo obtener un mapa de bits con este comando

 Bitmap bm = BitmapFactory.decodeByteArray(seperatedBytes, 0, seperatedBytes.length); 

Pero el mapa de bits tiene un tamaño de 0 KB.

La imagen que estoy recibiendo es una imagen cruda de esta cámara . Desafortunadamente, recuperar una imagen JPEG pre-comprimida no es una opción porque necesito escala de grises de 4 bits.

Si la imagen que entra es sólo en 2400 bytes, eso significa que hay dos píxeles por byte (4 bits cada uno). Sólo está dando el búfer de bytes 2400 * 4 = 9600 bytes cuando un ARGB_8888 necesita 4 bytes por píxel, o 60 * 80 * 4 = 19200 .

Necesita dividir cada byte entrante en un valor de nibble superior / inferior, luego aplicarlo a los siguientes 8 bytes (excluyendo alfa). Puede ver esta respuesta para un ejemplo de cómo dividir bytes.

Básicamente:

  • Dividir el byte entrante i en dos nibbles, ia y ib
  • Aplicar ia a los bytes salientes i*8 a (i*8)+2
  • Aplicar ib a los bytes salientes (i*8)+4 a (i*8)+6
  • Los bytes (i*8)+3 y (i*8)+7 son alfa ( 0xFF )

Una vez que tenga el tamaño adecuado byte buffer, usted debe ser capaz de utilizar decodeByteArry() sin problemas.

Si te entiendo correctamente tienes una matriz de bytes, cuyos bytes contienen 2 valores de escala de grises cada uno. Yo diría que un valor de escala de grises puede ser considerado como un valor de intensidad simple, ¿no?

Así que lo primero que tiene que hacer es separar sus valores de escala de grises en bytes individuales cada uno, ya que BitmapFactory.decodeByteArray probablemente no puede manejar sus "medio bytes". Esto puede hacerse fácilmente mediante operaciones de bits. Para obtener el primer valor de 4 bits de su byte `0bxxxxxxxx`, debe cambiar a la derecha 4 veces:` 0bxxxxxxxx >> 4`, lo que daría lugar a `0b0000xxxx`. El segundo valor se puede obtener de forma bit a bit o con el patrón `0b00001111`:` 0b00001111 ^ 0bxxxxxxxx` que conduciría a `0b0000xxxx`. (Para obtener información detallada sobre las operaciones de bits, consulte aquí: Operaciones de bits )

Esos dos valores ahora se pueden almacenar en una nueva matriz de bytes. Si lo hace por cada par de half-bytes, obtendrá una matriz de bytes completos y un tamaño doble al final.

No estoy seguro de si esto ya es suficiente para 'BitmapFactory.decodeByteArray' o si tiene que repetir cada byte 4 veces para cada RGBA-Channel, lo que aumentaría el tamaño de su matriz de bytes de nuevo por cuatro veces el tamaño original . Espero no haber notado nada y mis sugerencias ayudan;)

  • Android drawBitmap rendimiento de lotes de mapas de bits?
  • Cambiar gradualmente el fondo de gradiente del widget
  • Cómo cambiar el tamaño y la posición de Drawables dentro de un LayerDrawable en Android
  • ¿Es posible mostrar una miniatura de vídeo desde una URL en Android 4 o superior?
  • ¿Por qué tanta memoria?
  • Cómo enmascarar Bitmap con el sombreado LinearGradient correctamente?
  • El envío de entrada de ANR excedió el tiempo de espera en Android 4.4
  • La aplicación se bloquea al escalar el mapa de bits en lienzo
  • Cómo escalar el mapa de bits antes de mostrarlo en el mapa?
  • Cómo desenfocar un mapa de bits (Android)?
  • Tamaño de imagen de mapa de bits de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.