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 error " Bitmap too large to be uploaded into a texture (1944x2592, max=2048x2048)"
So to be able to show images with too high resolution im using:
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); }
This works but I don't really want to hardcode the maximum value of 2048 as I have in the if-statement now, but I cant find out how to get a the max allowed size of the bitmap for a device
Any ideas?
To solve my problem I should: Remove the ems-tag, set android:layout_width to "wrap_content" and set both minWidth and maxWidth to the maximum width.
Simple, use relative layout with the set margin code. Set the margins between each text view, button, etc and it will look the same on every phone. android:layout_marginTop="10dp" // change Top to Bottom, Left or Right for what you need.
Use “wrap_content” and “match_parent” To ensure that your layout is flexible and adapts to different screen sizes, you should use "wrap_content" and "match_parent" for the width and height of some view components.
Smallest width = 1080 / (dpi / 160) It can be found in this Android documentation in the form of px = dp * (dpi / 160), where px is the actual number of pixels (1080) and dp is the smallest width.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With