Compresión de mapa de bits y optimización de velocidad en Android

Estoy tratando con una aplicación de AR en Android que se basa en la salida de la cámara. Estoy trabajando en una parte del código para guardar tres archivos de imagen: la imagen en bruto, la superposición de la pantalla y la imagen compuesta con superposición dibujada en (posiblemente superfluo, dado los otros dos). El tamaño de la imagen nativa para mi cámara es 2592×1944.

En este momento mi operación de ahorro está tardando más de lo que me gustaría. Estoy haciendo la imagen de ahorro con un AsyncTask, pero la parte de ahorro real se reduce a lo siguiente:

public void onPictureTaken(byte[] data, Camera camera){ Size sz = camera.getParameters().getPictureSize(); TimingLogger tl = new TimingLogger("CodeTiming", "Start Saving"); String fileName = getNameFromTime(); tl.addSplit("Start Pic Save"); // The Picture itself ImageFile photo = new ImageFile(fileName+"_image.jpg"); photo.write(data); tl.addSplit("Start Overlay Save"); // The overlay with blank background Bitmap bmp = Bitmap.createBitmap(sz.width,sz.height,Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bmp); DrawStuffOnCanvas(canvas); ImageFile overlay = new ImageFile(fileName+"_overlay.png"); overlay.write(bitmapToByteArray(bmp,Bitmap.CompressFormat.PNG)); tl.addSplit("Start Overlay Onto Pic Save"); // The picture with the overlay drawn on Options options = new Options(); options.inDither = false; options.inPreferredConfig = Bitmap.Config.ARGB_8888; Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length, options); picture = picture.copy(Bitmap.Config.ARGB_8888, true); Canvas canvas2 = new Canvas(picture); DrawStuffOnCanvas(canvas2); ImageFile overlay2 = new ImageFile(fileName+"_combo.jpg"); overlay2.write(bitmapToByteArray(picture,Bitmap.CompressFormat.JPEG)); tl.addSplit("Start Metadata Save"); //Save picture metadata, not relevant to question tl.addSplit("Done"); tl.dumpToLog(); } 

La conversión del mapa de bits en el byte [] se realiza mediante:

 byte[] bitmapToByteArray(Bitmap b,Bitmap.CompressFormat fmt){ ByteArrayOutputStream baos = new ByteArrayOutputStream(); b.compress(fmt, 100, baos); return baos.toByteArray(); } 

Tenga en cuenta que todos los objetos de archivo (por ejemplo, ImageFile) son personalizados, pero la información relevante necesaria es que manejan la escritura de un byte [] utilizando un FileOutputStream. He aquí un dump de sincronización reciente para esta ejecución.

 Start Saving: begin Start Saving: 4 ms, Start Pic Save Start Saving: 86 ms, Start Overlay Save Start Saving: 3576 ms, Start Overlay Onto Pic Save Start Saving: 2066 ms, Start Metadata Save Start Saving: 15 ms, Done Start Saving: end, 5747 ms 

Hay un poco de variabilidad, en cualquier lugar de alrededor de 5-15 segundos por guardar. La superposición (esencialmente líneas dibujadas en la pantalla) se está guardando actualmente como un PNG para la transparencia, y debido a los artefactos en los bordes de línea agudos causados ​​por la compresión JPEG. Siguiendo la lógica de esta pregunta , vi que si cambio la superposición a un JPEG, me corté el tiempo para ese paso por la mitad. Como puede ver, implementé ese cambio para la imagen compuesta (los bordes afilados ya están borrosos por la propia imagen), lo que ahorró unos 20 segundos en ese paso de compresión.

Así que mi pregunta es esta. ¿Hay algo que pueda hacer para ahorrar tiempo en mi compresión de la superposición, pero mantener la salida PNG? O, alternativamente, ¿hay algo más que estoy haciendo aquí que está perdiendo mucho tiempo que podría acelerar la operación general de salvar? Entonces no tendría que preocuparse de PNG vs JPEG tanto.

Mecanismo de aceleración dramática:

Utilice RGB_565 en lugar de ARGB_8888 mientras que posible (p. Ej., Ningún píxel transparente)

Además, la operación de "copia" toma más tiempo que dibujar ese mapa de bits en la lona. Simplemente puede crear un mapa de bits vacío y dibujar la imagen original.

  1. La compresión de PNG es mucho más lenta que la compresión JPEG , especialmente cuando el tamaño de mapa de bits es alto.
  2. Utilice RGB_565 en lugar de ARGB_8888 si no le interesa la transparencia.

Más información aquí: https://stackoverflow.com/a/33299613/4747587

  • Rendimiento de Android xml vs java layouts
  • ¿Mostrar un mapa enorme con un buen rendimiento en Android?
  • Boot complete broadcast procesado en serie en KITKAT 4.4.2 <ACTION_BOOT_COMPLETED> <ActivityManagerService.java>
  • ¿La pantalla de bienvenida de Android es blanca al principio?
  • Manejo de mapas de bits grandes
  • ¿Android NDK da aceleración para enviar int sobre sockets?
  • Rendimiento en Android Juego
  • Mejorando la velocidad de getpixel () y setpixel () en Android Bitmap
  • ¿Es Hibernate un exceso para una aplicación de Android?
  • Falta el puerto reenviado en el Visor de jerarquía: Uso de Android Studio
  • Hashmap vs Bundle en Android Eficiencia y comparación de rendimiento
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.