¿Cómo puedo convertir una image de datos sin procesar en Android sin ningún tipo de munging?

Tengo datos de imágenes en bruto (pueden ser .png, .jpg, …) y quiero que se conviertan en Android sin cambiar su profundidad de píxel (bpp). En particular, cuando cargo una image en escala de grises (8 bpp) que quiero usar como alfa ( glTexImage( ) con GL_ALPHA ), la convierte a 16 bpp (presumiblemente 5_6_5 ).

Si bien tengo un plan B (en realidad, estoy probablemente en el plan 'E' por ahora, esto realmente se está volviendo molesto) Me gustaría descubrir una manera fácil de hacerlo utilizando lo que está disponible en la API.

Hasta ahora, estoy usando BitmapFactory.decodeByteArray() .

Mientras estoy en eso. Estoy haciendo esto desde un entorno nativo a través de JNI (pasando el buffer de C, y un nuevo buffer de C a Java). Cualquier solución portátil en C / C ++ sería preferible, pero no quiero introducir nada que pueda romperse en futuras versiones de Android, etc.

Tenga en count que, dado que las imágenes JPEG usan un espacio de color Y o YUV, en realidad no tienen una profundidad de píxel y, por lo tanto, no hay una profundidad "correcta" para ellas. Dicho esto, está en lo cierto al esperar una image en escala de grises de 8bpp al decodificar un JPEG monocromo.

No sé de una API disponible para lograr lo que estás tratando de hacer de forma automática. Sin embargo, puede solicitar una profundidad específica utilizando las opciones preferidas de BitmapFactory :

  BitmapFactory.Options opts = new BitmapFactory.Options(); // This option is suitable for monochrome JPEGs: opts.inPrefernetworkingConfig = Bitmap.Config.ALPHA_8; // This option is suitable for 32-bit PNGs: opts.inPrefernetworkingConfig = Bitmap.Config.RGB_8888; bitmap = BitmapFactory.decodeByteArray(data, 0, len, opts); 

Esto sigue siendo una pista para el decodificador y no garantiza que siempre obtendrá lo que espera. Tengo sugerencias adicionales:

  • incrusta tus propias versiones de libPNG y / o libJPEG. Sugiero probar libjpeg-turbo, que permite ajustar aún más los espacios de colors disponibles.
  • en lugar de utilizar PNG o JPEG como su formatting de intercambio, use uno o varios formattings de compression de texturas adecuados para sus dispositivos de destino; hay herramientas disponibles para convertir PNG a ETC1, que es parte del estándar OpenGL ES. Tal vez agregue una capa de gzip además de eso.
  • no dude en experimentar y probar methods generics de compression : almacene su image tal como la libgz en la tarjeta de video y libgz usando libgz o libbzip2 . Tengo imágenes que se vuelven significativamente más pequeñas usando bzip2 en una versión no comprimida que cuando se tritura con pngcrush . Esa puede ser una compensación aceptable.

¡Espero que esto ayude!

Hay una pregunta en StackOverflow que hace una pregunta similar y hay un par de soluciones publicadas allí. ¿Qué has intentado hasta ahora?

Para convertir en bruto a la image, la mejor API de Java es ImageIO .

Documentación: API ImageIO @ Java

Puede ser de ayuda.