2011-01-27 16 views
18

Estoy trabajando en una aplicación de procesamiento de imágenes para Android que reconoce la notación musical de las imágenes tomadas de las partituras musicales.¿Es posible cortar un mapa de bits en pedazos pequeños sin cargar todo en la memoria?

Intenté cargar toda la imagen en un mapa de bits utilizando el método BitmapFactory.decodeFile(imgPath), pero como mi teléfono no tiene suficiente memoria, recibo un error de "tamaño de pila de VM". Para evitar esto, me gustaría cortar la imagen completa en pedazos más pequeños, pero no estoy seguro de cómo hacer eso.

También vi que era posible reducir el tamaño de la memoria del mapa de bits utilizando el inSampleSize property de la clase BitmapFactory.Option, pero si hago lo que no voy a conseguir la imagen de alta resolución que necesito para la notación musical proceso de reconocimiento.

¿Hay alguna forma de manejar esto sin ir a NDK?

+0

¿Es realmente el archivo codificado como mapa de bits? ¿Puedes comprimir la imagen de origen para que no sea tan grande? Para solo música, no debería necesitar muchos colores ... ¿Qué tan grande en bytes y resolución son las imágenes con las que está trabajando? – Matt

+0

¿El mapa de bits es suyo o del usuario? Si es tuyo, considera almacenarlo previamente cortado y/o en menos colores. Si es del usuario, ¿se trata de un caso límite o una entrada típica? Si es límite, implemente la validación/manejo elegante de errores. Si es típico, reconsidere su elección de plataforma. –

+0

El mapa de bits es del usuario. Él tomará la foto de la cámara móvil. Tengo que usar el mapa de bits más grande posible porque en el proceso de reconocimiento la efectividad proviene de esto. Gracias por editar y lo siento por mi pobre inglés. – OffCS

Respuesta

1

Si es de una cámara, es probable que la imagen sea en formato jpeg. Puede usar una biblioteca jpeg externa, ya sea en java o mediante el NDK, lo que sea que pueda encontrar, para darle un mejor control y cargarla pieza por pieza. Si lo necesita como android.graphics.Bitmap entonces sospecho que necesitará volver a codificar la subimagen como PNG o JPEG y pasarla a BitmapFactory.decodeByteArray(). (Si la memoria es una preocupación, asegúrese de olvidar rápidamente sus referencias a las piezas del mapa de bits para que el recolector de basura pueda ejecutarse efectivamente).

La misma técnica también funcionará si el gráfico de entrada es formato PNG, o casi cualquier cosa, siempre que pueda encontrar el código de decodificación adecuado para ello.

Creo que al cargar la imagen por partes, se está estableciendo un desafío algorítmico al decidir qué partes de la misma le interesan realmente los detalles completos. Observé que BitmapFactory.Options incluye la opción de submuestra, que podría ser útil si desea analizar una visión general de la imagen para decidir qué regiones cargar con todo detalle.

1

Si se trata de imágenes JPEG, consulte mi respuesta a this question, así como this example.

No sé cómo es posible obtener libijg en Android, pero si lo es, vale la pena intentarlo.

27

Android 2.3.3 tiene una nueva API llamada android.graphics.BitmapRegionDecoder que le permite hacer exactamente lo que desea.

Usted podría, por ejemplo, hacer lo siguiente:

BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false); 
Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null); 

fácil :)

+0

Esta clase está en 2.3.3, y esto está bien si estás de acuerdo con que tu aplicación solo funcione en 2.3 .3 y superior, pero ¿y las versiones anteriores? –

+3

Podrías tomar el código del repositorio git y usarlo en tu aplicación :) –

+0

@RomainGuy, ¿podrías explicarnos un poco sobre cómo hacerlo? Parece que el código hace referencia a los métodos nativos ... ¿también necesitamos agarrar esos métodos nativos de git, y compilar con NDK, o es la clase java suficiente por sí misma? – snapfractalpop

Cuestiones relacionadas