Android image decoding massive memory consumption

Dexter

I wanted to compress/re-scale an image before uploading. Here is the code that I use for compression. It works well for very large images, but this particular image ate up a huge amount of RAM. I have linked the necessary images. Here is the code that I use.

I had to forcefully call System.gc() to release the overly used memory.

public static File compressImage(File image) throws IOException {

        // Decode just the boundaries
        final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
        mBitmapOptions.inJustDecodeBounds = true;

        final FileInputStream fileInputStream = new FileInputStream(image);
        final Bitmap temporary = BitmapFactory.decodeStream(fileInputStream, null, mBitmapOptions);
        if (temporary != null)
            temporary.recycle();

        // Calculate inSampleSize
        // Raw height and width of image
        final int height = mBitmapOptions.outHeight;
        final int width = mBitmapOptions.outWidth;
        final int sideLength = 800;
        closeQuietly(fileInputStream);

        int reqHeight = height;
        int reqWidth = width;
        final int inDensity;
        final int inTargetDensity;

        if (height > width) {

            inDensity = height;
            inTargetDensity = reqHeight;
            if (height > sideLength) {

                reqHeight = sideLength;
                reqWidth = (width * sideLength) / height;
            }
        } else if (width > height) {

            inDensity = width;
            inTargetDensity = reqWidth;
            if (width > sideLength) {
                reqWidth = sideLength;
                reqHeight = (height * sideLength) / width;
            }
        } else {

            reqWidth = sideLength;
            reqHeight = sideLength;
            inDensity = height;
            inTargetDensity = reqHeight;
        }

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

        //now go resize the image to the size you want
        mBitmapOptions.inSampleSize = inSampleSize;
        mBitmapOptions.inDither = true;
        mBitmapOptions.inPreferQualityOverSpeed = true;
        mBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
        mBitmapOptions.inJustDecodeBounds = false;
        mBitmapOptions.inScaled = true;
        mBitmapOptions.inDensity = inDensity;
        mBitmapOptions.inTargetDensity = inTargetDensity * mBitmapOptions.inSampleSize;

        final File tempFile = File.createTempFile("compressed_profile_photo", null);
        final FileInputStream fInputStream = new FileInputStream(image);
        final FileOutputStream fileOutputStream = new FileOutputStream(tempFile);

        // will load & resize the image to be 1/inSampleSize dimensions
        final Bitmap bitmap = BitmapFactory.decodeStream(fInputStream, null, mBitmapOptions);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 85, fileOutputStream);
        fileOutputStream.flush();
        bitmap.recycle();
        closeQuietly(fInputStream, fileOutputStream);

        //noinspection ResultOfMethodCallIgnored
        image.delete();
        return tempFile;
    }
Dexter

There was a silly mistake in this part :

if (height > width) {

            inDensity = height;
            inTargetDensity = reqHeight;
            if (height > sideLength) {

                reqHeight = sideLength;
                reqWidth = (width * sideLength) / height;
            }
        } else if (width > height) {

            inDensity = width;
            inTargetDensity = reqWidth;
            if (width > sideLength) {
                reqWidth = sideLength;
                reqHeight = (height * sideLength) / width;
            }
        }

it should be this :

if (height > width) {

            if (height > sideLength) {

                reqHeight = sideLength;
                reqWidth = (width * sideLength) / height;
            }
            inDensity = height;
            inTargetDensity = reqHeight;

        } else if (width > height) {

            if (width > sideLength) {
                reqWidth = sideLength;
                reqHeight = (height * sideLength) / width;
            }
            inDensity = width;
            inTargetDensity = reqWidth;

        }

Because of this resize was not even happening !

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related