title: Android image decoding massive memory consumption
body: <p>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 <a href="https://www.dropbox.com/s/a3otzrcrbdumvnb/190_bottom_superhires.jpg?dl=1" rel="nofollow">particular image</a> ate up a <a href="https://www.dropbox.com/s/bgmuenb531t04tj/Screen%20Shot%202015-09-11%20at%206.54.24%20pm%20%282%29.png?dl=0" rel="nofollow">huge amount of RAM</a>. I have linked the necessary images. Here is the code that I use.</p>
  
  <p>I had to forcefully call System.gc() to release the overly used memory.</p>
  
  <pre><code>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 &gt; width) {
  
              inDensity = height;
              inTargetDensity = reqHeight;
              if (height &gt; sideLength) {
  
                  reqHeight = sideLength;
                  reqWidth = (width * sideLength) / height;
              }
          } else if (width &gt; height) {
  
              inDensity = width;
              inTargetDensity = reqWidth;
              if (width &gt; sideLength) {
                  reqWidth = sideLength;
                  reqHeight = (height * sideLength) / width;
              }
          } else {
  
              reqWidth = sideLength;
              reqHeight = sideLength;
              inDensity = height;
              inTargetDensity = reqHeight;
          }
  
          int inSampleSize = 1;
  
          if (height &gt; reqHeight || width &gt; 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) &gt; reqHeight &amp;&amp; (halfWidth / inSampleSize) &gt; 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 &amp; 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;
      }
  </code></pre>