0
votes

I have an android application where I load resource image files and create textures for them so I can render them using OpenGL. However I am using mipmaps and the image dimensions must be powers of two. This is why I need to possibly increase the width or height of the given Bitmap before making the texture.

Here is my code that currently does the work:

    Bitmap bitmap = BitmapFactory.decodeResource(this.context.getResources(), resourceId);

    Bitmap newBitmap = Bitmap.createBitmap(nextPowerOfTwo(bitmap.getWidth()), 
            nextPowerOfTwo(bitmap.getHeight()), bitmap.getConfig());

    int x=0,y=0,width=bitmap.getWidth(),height=bitmap.getHeight();
    int [] pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, x, y, width, height);
    newBitmap.setPixels(pixels, 0, width, x, y, width, height);
    bitmap.recycle();
    gl.glGenTextures(1, textures, textureCount);
            ...

This worked perfectly on my Asus TF101 and Nexus 4 but I am getting an OutOfMemory exception for Galaxy S3 (and probably more devices), in the following line:

int [] pixels = new int[width * height];

From doing some reading I realized that the call to Bitmap.createBitmap is also memory expensive, and I am trying to think of a way to reduce the memory waste. First idea that comes to mind is using a smaller 2D array for 'int[] pixels' and copying fewer pixels at a time. But I am wondering if there is any other more efficient way to do this.

1

1 Answers

1
votes

since you are just creating a scaled bitmap, this method should be the solution to your problem: http://developer.android.com/reference/android/graphics/Bitmap.html#createScaledBitmap(android.graphics.Bitmap, int, int, boolean)

Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, nextPowerOfTwo(bitmap.getWidth()), nextPowerOfTwo(bitmap.getHeight()), false);
bitmap.recycle();