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?
- Convertir ShaderToy a Shader de fragmentos
- GL El ejemplo del papel pintado muestra solamente la pantalla verde en emulador, pero está trabajando en el dispositivo
- ApplicationStatus clase E / SysUtils: ApplicationContext es null en ApplicationStatus
- Primeros pasos para crear un efecto de chroma key utilizando la cámara android
- Uso de OpenGL para reemplazar Canvas - Android
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.
- Aplicar filtros personalizados a la salida de la cámara
- Rendimiento lento de glTexSubImage2D en Nexus 10 / Android 4.2.2 (Samsung Exynos 5 con Mali-T604)
- ¿Cuándo sincronizo métodos o utilizo bloques sincronizados en mis métodos en un juego de Android?
- Límites de memoria de Android Graphics
- Verificar si el punto está dentro de un cono en el espacio 3D
- Android: actualiza el mapa de bits del hilo del temporizador
- Cómo dibujar círculo básico en OpenGL ES 2.0 Android
- Cómo hacer la detección de objetos en opengl Android?
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.
- ¿Por qué LogCat muestra todos los elementos como advertencias (naranja)?
- ¿Cuál es la diferencia entre getIntent () y obtener la intención de savedInstanceState?