Android: ancho y alto máximos permitidos de bitmap

Im creando una aplicación que necesita decodificar imágenes de gran tamaño para mapas de bits que se mostrarán en un ImageView.

Si bash decodificarlos directamente en un bitmap, aparece el siguiente error: “Mapa de bits demasiado grande para ser cargado en una textura (1944×2592, max = 2048×2048)”

Para poder mostrar imágenes con una resolución demasiado alta, yo uso:

Bitmap bitmap = BitmapFactory.decodeFile(path); if(bitmap.getHeight()>=2048||bitmap.getWidth()>=2048){ DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int width = metrics.widthPixels; int height = metrics.heightPixels; bitmap =Bitmap.createScaledBitmap(bitmap, width, height, true); } 

Esto funciona, pero realmente no quiero codificar el valor máximo de 2048 como lo tengo ahora en el enunciado if, pero no puedo encontrar cómo obtener el tamaño máximo permitido del bitmap para un dispositivo.

¿Algunas ideas?

Este límite debería provenir de la implementación subyacente de OpenGL. Si ya está usando OpenGL en su aplicación, puede usar algo como esto para obtener el tamaño máximo:

 int[] maxSize = new int[1]; gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxSize, 0); // maxSize[0] now contains max size(in both dimensions) 

Esto muestra que tanto mi Galaxy Nexus como Galaxy S2 tienen un máximo de 2048×2048.

Desafortunadamente, si aún no lo está usando, la única forma de obtener un contexto OpenGL para llamar esto es crear uno (incluyendo la vista de superficie, etc.), que es una sobrecarga solo para consultar un tamaño máximo.

Otra forma de obtener el tamaño máximo permitido sería recorrer todas las configuraciones de EGL10 y realizar un seguimiento del tamaño más grande.

 public static int getMaxTextureSize() { // Safe minimum default size final int IMAGE_MAX_BITMAP_DIMENSION = 2048; // Get EGL Display EGL10 egl = (EGL10) EGLContext.getEGL(); EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); // Initialise int[] version = new int[2]; egl.eglInitialize(display, version); // Query total number of configurations int[] totalConfigurations = new int[1]; egl.eglGetConfigs(display, null, 0, totalConfigurations); // Query actual list configurations EGLConfig[] configurationsList = new EGLConfig[totalConfigurations[0]]; egl.eglGetConfigs(display, configurationsList, totalConfigurations[0], totalConfigurations); int[] textureSize = new int[1]; int maximumTextureSize = 0; // Iterate through all the configurations to located the maximum texture size for (int i = 0; i < totalConfigurations[0]; i++) { // Only need to check for width since opengl textures are always squared egl.eglGetConfigAttrib(display, configurationsList[i], EGL10.EGL_MAX_PBUFFER_WIDTH, textureSize); // Keep track of the maximum texture size if (maximumTextureSize < textureSize[0]) maximumTextureSize = textureSize[0]; } // Release egl.eglTerminate(display); // Return largest texture size found, or default return Math.max(maximumTextureSize, IMAGE_MAX_BITMAP_DIMENSION); } 

De mi prueba, esto es bastante confiable y no requiere que crees una instancia. En cuanto al rendimiento, esto tomó 18 milisegundos para ejecutarse en mi Note 2 y solo 4 milisegundos en mi G3.

esto decodificará y escalará la imagen antes de cargarla en la memoria, simplemente cambie el paisaje y el retrato al tamaño que realmente desea

 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; String imageType = options.outMimeType; if(imageWidth > imageHeight) { options.inSampleSize = calculateInSampleSize(options,512,256);//if landscape } else{ options.inSampleSize = calculateInSampleSize(options,256,512);//if portrait } options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeFile(path,options); 

método para calcular el tamaño

 public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // Calculate ratios of height and width to requested height and width final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } 

Si está en el nivel de API 14+ (ICS), puede usar las funciones getMaximumBitmapWidth y getMaximumBitmapHeight en la clase Canvas . Esto funcionaría tanto en hardware acelerado como en capas de software.

Creo que el hardware de Android debe al menos soportar 2048×2048, por lo que sería un valor mínimo seguro. En las capas de software, el tamaño máximo es 32766×32766.

El límite 2048 * 2048 es para GN. GN es un dispositivo xhdpi y tal vez pones la imagen en el cubo de densidad incorrecto. Moví una imagen de 720 * 1280 de drawable a drawable-xhdpi y funcionó.

Gracias por la respuesta de Romain Guy. Aquí está el enlace de su respuesta.