0

My app displays pictures takes from the camera. On some devices, it happens that the pictures ain't displayed on an ImageView because of the error message: Bitmap too large to be uploaded into a texture (1624x2251, max=2048x2048) To solve this issue, the app simply scales the image down to the maximum supported texture size. The code looks like this:

int[] maxTextureSize = new int[1];
GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);
if (maxTextureSize[0] < 2048) {
    maxTextureSize[0] = 2048;
}

if (bitmap.getWidth() > maxTextureSize[0] || bitmap.getHeight() > maxTextureSize[0]) {
    float factor = Math.min((float)maxTextureSize[0] / (float)bitmap.getWidth(), (float)maxTextureSize[0] / (float)bitmap.getHeight());
    int newWidth = (int) (bitmap.getWidth() * factor);
    int newHeight = (int) (bitmap.getHeight() * factor);

    bitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, false);
}

Now this works in most of the cases, except from time to time (randomly), when GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE) causes the following error message without returning the texture size:

call to OpenGL ES API with no current context (logged once per thread)

Now the question is, how can the app reliably determine the maximum displayable bitmap size of an ImageView? Preferable without setting up an OpenGL context. Is there any alternative?

SePröbläm
  • 5,142
  • 6
  • 31
  • 45
  • Possible duplicate of [GLES10.glGetIntegerv returns 0 in Lollipop only](http://stackoverflow.com/questions/26985858/gles10-glgetintegerv-returns-0-in-lollipop-only) – Reto Koradi Feb 14 '16 at 17:16
  • Thank you for pointing this out. Is there no other way to query ImageView's maximum displayable image size other then setting up a full blown OpenGL context? – SePröbläm Feb 15 '16 at 00:00

1 Answers1

0

Take a look at Displaying Bitmaps Efficiently. It's a great in-depth official guide tackling the exact problem you're facing.

From this answer on stack overflow, you can use:

MemoryInfo mi = new MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem / 1048576L;

//Percentage can be calculated for API 16+
long percentAvail = mi.availMem / mi.totalMem;

to get the memory available to your app. Using this and the size of your bitmap, you can figure out exactly how big your image can be.

the app simply scales the image down to the maximum supported texture size

I must say, you're probably trying to render images bigger than can be displayed. Are you considering the device's resolution before rendering the bitmap? Not a whole lot of devices are 2048 pixels wide.

Community
  • 1
  • 1
Aditya Anand
  • 776
  • 2
  • 9
  • 29
  • Thank you for your advise. The available memory is an unsuitable approach - even if there's not enough memory available, the GC would kick in and the resulting available memory could be way more than what ImageView is able to display. Nice idea, but clearly the wrong approach. The device resolution would be saver. But there are cases where the max texture size is bigger than the next power of two of the screen resolution - in which case the bitmap would be scaled down even if it's unnecessary. – SePröbläm Feb 15 '16 at 00:19