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

时间:2013-03-09 17:36:55

标签: android bitmap

我创建的应用程序需要将大图像解码为位图才能在ImageView中显示。

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

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

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的最大值,但是我无法找到如何获得设备位图的最大允许大小

有什么想法吗?

5 个答案:

答案 0 :(得分:13)

获得最大允许大小的另一种方法是遍历所有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毫秒。

答案 1 :(得分:9)

此限制应来自底层的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最多都是2048x2048。

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

如果您使用的是API等级14+(ICS),则可以使用getMaximumBitmapWidth课程中的getMaximumBitmapHeightCanvas功能。这适用于硬件加速层和软件层。

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

答案 4 :(得分:0)

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

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