Android:位图的最大允许宽度和高度

我正在创建一个需要将大图像解码为位图的应用程序,以便在ImageView中显示。

如果我只是尝试将它们直接解码为位图,我会收到以下错误“位图太大而无法上传到纹理中(1944×2592,max = 2048×2048)”

因此,为了能够使用以下方法显示分辨率过高的图像:

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); } 

这有效,但我真的不想像现在的if语句那样硬编码2048的最大值,但我无法find如何获得设备位图的最大允许大小

有任何想法吗?

Solutions Collecting From Web of "Android:位图的最大允许宽度和高度"

此限制应来自底层的OpenGL实现。 如果你已经在你的应用程序中使用OpenGL,你可以使用这样的东西来获得最大尺寸:

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

这表明我的Galaxy Nexus和Galaxy S2的最大值都是2048×2048。

不幸的是,如果您还没有使用它,获取OpenGL上下文来调用它的唯一方法是创建一个(包括surfaceview等),这只是查询最大大小的大量开销。

获得最大允许大小的另一种方法是遍历所有EGL10配置并跟踪最大尺寸。

 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); } 

从我的测试来看,这非常可靠,不需要您创建实例。 性能方面,我在Note 2上执行了18毫秒,在G3上只执行了4毫秒。

这将在加载到内存之前解码和缩放图像,只需将横向和纵向更改为您实际需要的大小

 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); 

计算尺寸的方法

 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; } 

如果您使用的是API级别14+(ICS),则可以在Canvas类上使用getMaximumBitmapWidthgetMaximumBitmapHeight函数。 这适用于硬件加速和软件层。

我相信Android硬件必须至少支持2048×2048,因此这将是一个安全的最低价值。 在软件层上,最大大小为32766×32766。

GNA的2048 * 2048限制。 GN是一个xhdpi设备,也许你把图像放在错误的密度桶中。 我将720 * 1280图像从drawable移动到drawable-xhdpi并且它工作了。

感谢Romain Guy的回答。 这是他答案的链接 。