Android : Maximum allowed width & height of bitmap

前端 未结 5 1822
广开言路
广开言路 2020-11-27 04:37

Im creating an app that needs to decode large images to bitmaps to be displayed in a ImageView.

If i just try to decode them straight to a bitmap i get the following

相关标签:
5条回答
  • 2020-11-27 05:08

    Another way of getting the maximum allowed size would be to loop through all EGL10 configurations and keep track of the largest size.

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

    From my testing, this is pretty reliable and doesn't require you to create an instance. Performance-wise, this took 18 milliseconds to execute on my Note 2 and only 4 milliseconds on my G3.

    0 讨论(0)
  • 2020-11-27 05:09

    this will decode and scale image before loaded into memory,just change landscape and portrait to the size you actually want

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

    method for calculating size

    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;
    }
    
    0 讨论(0)
  • 2020-11-27 05:17

    If you're on API level 14+ (ICS) you can use the getMaximumBitmapWidth and getMaximumBitmapHeight functions on the Canvas class. This would work on both hardware accelerated and software layers.

    I believe the Android hardware must at least support 2048x2048, so that would be a safe lowest value. On software layers, the max size is 32766x32766.

    0 讨论(0)
  • 2020-11-27 05:29

    The 2048*2048 limit is for GN. GN is a xhdpi device and perhaps you put the image in the wrong density bucket. I moved a 720*1280 image from drawable to drawable-xhdpi and it worked.

    Thanks for the answer by Romain Guy. Here's the link of his answer.

    0 讨论(0)
  • 2020-11-27 05:32

    This limit should be coming from the underlying OpenGL implementation. If you're already using OpenGL in your app, you can use something like this to get the maximum size:

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

    This shows that my both my Galaxy Nexus and Galaxy S2 have a maximum of 2048x2048.

    Unfortunately, if you're not already using it, the only way to get an OpenGL context to call this from is to create one(including the surfaceview, etc), which is a lot of overhead just to query a maximum size.

    0 讨论(0)
提交回复
热议问题