Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does documentation sample divide by 2 to calculate inSampleSize for Bitmap loading?

In the Android Training documentation is an article about loading large bitmaps efficiently that discusses calculating an inSampleSize to downsample an image when it's loaded. This is the code sample that's shared.

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

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

What doesn't quite make sense to me is the use of halfHeight and halfWidth here. Let's walk through a real world example so I can show what I mean.

I want to load a user's photo into an OpenGL texture. I've already queried to find that the GL_MAX_TEXTURE_SIZE is 4096. The user selects a photo which is 4320x2432, so I need to scale that down a little.

I make the call to my static helper method provided in the docs:

options.inSampleSize = BitmapUtils.calculateInSampleSize(options, maxTextureSize, maxTextureSize);

Stepping through this code, halfHeight will be 1216 and halfWidth will be 2160, and inSampleSize will only be other than 1 if that value divided by inSampleSize is still greater than the requested dimension.

When I run this setup, inSampleSize is set to 1, which doesn't scale the image down at all, and OpenGL throws a fit because that is larger than the GL_MAX_TEXTURE_SIZE.

My question is why do we divide by two here? I don't care if half of my image fits in the requested dimensions, I want the whole image to fit. Wouldn't it make more sense to keep bumping inSampleSize as long as (halfHeight / inSampleSize) > reqHeight and (halfWidth / inSampleSize) > reqWidth?

like image 677
rharter Avatar asked Oct 21 '22 10:10

rharter


1 Answers

This was my misunderstanding of the intention of this method. I thought we were looking for an inSampleSize that would decode a Bitmap to fit inside the requested dimensions. I see now that the method is intended to return a value to decode a Bitmap that would be as close as possible but not smaller than the requested size.

like image 93
rharter Avatar answered Nov 15 '22 06:11

rharter