Cómo lidiar con el límite de tamaño de textura de Android

Tengo el requisito de mostrar imágenes algo grandes en una aplicación de Android. En este momento estoy usando un ImageView con un mapa de bits de origen. Entiendo que openGL tiene una limitación independiente del dispositivo en cuanto al tamaño de las dimensiones de la imagen puede ser para que lo procese.

¿Hay alguna manera de mostrar estas imágenes (con ancho fijo, sin recortar) independientemente de este límite, aparte de dividir la imagen en varios elementos de ImageView?

Gracias.

UPDATE 01 Apr 2013 Todavía no hay suerte hasta ahora todas las sugerencias fueron para reducir la calidad de la imagen. Uno sugirió que podría ser posible pasar por alto esta limitación usando la CPU para hacer el procesamiento en lugar de usar la GPU (aunque podría tomar más tiempo para procesar). No entiendo, ¿realmente no hay forma de mostrar imágenes largas con un ancho fijo sin reducir la calidad de la imagen? Apuesto a que hay, me encantaría que alguien me al menos me indicara la dirección correcta.

Gracias a todos.

Puede utilizar BitmapRegionDecoder para dividir mapas de bits más grandes (requiere el nivel 10 de API). He escrito un método que utilizará esta clase y devolverá un solo Drawable que se puede colocar dentro de un ImageView :

 private static final int MAX_SIZE = 1024; private Drawable createLargeDrawable(int resId) throws IOException { InputStream is = getResources().openRawResource(resId); BitmapRegionDecoder brd = BitmapRegionDecoder.newInstance(is, true); try { if (brd.getWidth() <= MAX_SIZE && brd.getHeight() <= MAX_SIZE) { return new BitmapDrawable(getResources(), is); } int rowCount = (int) Math.ceil((float) brd.getHeight() / (float) MAX_SIZE); int colCount = (int) Math.ceil((float) brd.getWidth() / (float) MAX_SIZE); BitmapDrawable[] drawables = new BitmapDrawable[rowCount * colCount]; for (int i = 0; i < rowCount; i++) { int top = MAX_SIZE * i; int bottom = i == rowCount - 1 ? brd.getHeight() : top + MAX_SIZE; for (int j = 0; j < colCount; j++) { int left = MAX_SIZE * j; int right = j == colCount - 1 ? brd.getWidth() : left + MAX_SIZE; Bitmap b = brd.decodeRegion(new Rect(left, top, right, bottom), null); BitmapDrawable bd = new BitmapDrawable(getResources(), b); bd.setGravity(Gravity.TOP | Gravity.LEFT); drawables[i * colCount + j] = bd; } } LayerDrawable ld = new LayerDrawable(drawables); for (int i = 0; i < rowCount; i++) { for (int j = 0; j < colCount; j++) { ld.setLayerInset(i * colCount + j, MAX_SIZE * j, MAX_SIZE * i, 0, 0); } } return ld; } finally { brd.recycle(); } } 

El método comprobará si el recurso extraíble es menor que MAX_SIZE (1024) en ambos ejes. Si es así, sólo devuelve el dibujable. Si no es así, se romperá la imagen aparte y decodificar trozos de la imagen y colocarlos en un LayerDrawable .

Elegí 1024 porque creo que la mayoría de los teléfonos disponibles soportarán imágenes por lo menos tan grandes. Si quieres encontrar el límite de tamaño de textura real para un teléfono, tienes que hacer algunas cosas funky a través de OpenGL, y no es algo que quería bucear.

No estaba seguro de cómo estaban accediendo a sus imágenes, así que asumí que estaban en su carpeta dibujable. Si ese no es el caso, debería ser bastante fácil de refactorizar el método para tomar en cualquier parámetro que necesita.

Puede utilizar BitmapFactoryOptions para reducir el tamaño de la imagen. Puede utilizar somthing así:

 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 3; //reduce size 3 times 

¿Has visto cómo funcionan tus mapas? Había hecho una representación para los mapas una vez. Puede usar el mismo truco para mostrar su imagen.

Divida la imagen en cuadrados de azulejos (por ejemplo, de 128 x 128 píxeles). Cree renderizaciones de imagen personalizadas que representen los azulejos. Su imageView sabe qué parte del mapa de bits debe mostrar ahora y sólo muestra los mosaicos requeridos que los cargan desde su tarjeta sd. Usando tal mapa de azulejos puede mostrar imágenes sin fin.

Sería de ayuda si nos das las dimensiones de tu mapa de bits.

Por favor, entienda que OpenGL se ejecuta contra los límites matemáticos naturales.

Por ejemplo, hay una razón muy buena que una textura en OpenGL debe ser 2 a la potencia de x. Ésta es realmente la única manera que la matemáticas de cualquier downscaling se puede hacer limpia sin resto.

Por lo tanto, si nos das las dimensiones exactas del mapa de bits más pequeño que te está causando problemas, es posible que algunos de nosotros podamos decirte qué tipo de límite actual estás enfrentando.

  • Cómo crear el modelo de cara de usuario dinámico en android?
  • Alternativa para glBlitFrameBuffer () en OpenGL ES 2.0
  • Cómo dibujar una imagen de fondo grande con libgdx - las mejores prácticas?
  • Conversión YUV a RGB y visualización utilizando opengl es 2.0 de android ndk usando shaders
  • Android OpenGL ES Soporte en todas partes?
  • Pixels de Bitmap de Android: ¿escribir directamente al archivo?
  • Renderización de Android OpenGLES con C ++ y Java
  • ¿El tutorial Android de OpenGL de Google enseña álgebra lineal incorrecta?
  • ¿Cómo usar un vector de rotación y traducción OpenCV con OpenGL ES en Android?
  • OpenGL en Android versus iOS: optimizaciones, y donde difieren
  • La pintura con libgdx hace que los objetos parpadeen
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.