title: Rotate large images on Android
body: <p>I'm trying to rotate the large images made by the phone camera (8 megapixels). Just Bitmap.createBitmap with the rotated Matrix from the source Bitmap runs into OutOfMemoryError. That's why I'm trying to split into rotated pieces, and than combine them again into single rotated image to avoid holding in memory 2 large Bitmaps, but it takes up to 10 seconds even on my Samsung S3. Any other ways to do this?</p>
  
  <pre><code>   public static void rotateImage(File file)
              throws FileNotFoundException {
          long time = System.currentTimeMillis();
          List&lt;File&gt; fileList = new ArrayList&lt;File&gt;();
  
          // For the number of rows and columns
          int rowsCols = 3;
  
          Matrix matrix = new Matrix();
          matrix.postRotate(-90);
  
          int chunkHeight, chunkWidth;
  
          BitmapFactory.Options options = new BitmapFactory.Options();
          options.inJustDecodeBounds = true;
  
          BitmapFactory.decodeStream(new FileInputStream(file), null, options);
  
          int height = options.outHeight;
          int width = options.outWidth;
  
          chunkHeight = height / rowsCols;
          chunkWidth = width / rowsCols;
  
          BitmapFactory.Options o2 = new BitmapFactory.Options();
          o2.inSampleSize = 1;
          o2.inPurgeable = true;
          o2.inInputShareable = true;
          o2.inPreferredConfig = Bitmap.Config.ARGB_8888;
  
          Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file),
                  null, o2);
  
          // Cut the small rotated pieces and save to the files
          int yCoord = 0;
          for (int y = 0; y &lt; rowsCols; y++) {
              int xCoord = 0;
              for (int x = 0; x &lt; rowsCols; x++) {
                  split(chunkHeight, chunkWidth, yCoord, x, xCoord, y, bitmap,
                          matrix, fileList);
                  xCoord += chunkWidth;
              }
              yCoord += chunkHeight;
          }
          bitmap.recycle();
          Bitmap rotatedBitmap = Bitmap.createBitmap(height, width,
                  Bitmap.Config.ARGB_8888);
          Canvas canvas = new Canvas(rotatedBitmap);
  
          // Combine the small pieces into the one output canvas
          int xCoord;
          xCoord = 0;
          for (int x = 0; x &lt; rowsCols; x++) {  
              yCoord = 0;
              for (int y = 0; y &lt; rowsCols; y++) {
                  combineIntoCanvas(o2, canvas, xCoord, yCoord, fileList);
                  yCoord -= chunkWidth;
              }
              xCoord += chunkHeight;
          }
  
          //Save the bitmap to the file
          rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90,
                  new FileOutputStream(file, false));
          rotatedBitmap.recycle();
          Log.add("combined in " + (System.currentTimeMillis() - time));
      }
  
      private static void combineIntoCanvas(BitmapFactory.Options o2,
              Canvas canvas, int xCoord, int yCoord, List&lt;File&gt; fileList)
              throws FileNotFoundException {
          File file = fileList.get(0);
          Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file),
                  null, o2);
          canvas.drawBitmap(bitmap, xCoord, yCoord, null);
          bitmap.recycle();
          file.delete();
          fileList.remove(0);
      }
  
      private static void split(int chunkHeight, int chunkWidth, int yCoord,
              int x, int xCoord, int y, Bitmap bitmap, Matrix matrix,
              List&lt;File&gt; fileList) throws FileNotFoundException {
  
          Bitmap pieceOfBitmap = Bitmap.createBitmap(bitmap, xCoord, yCoord,
                  chunkWidth, chunkHeight, matrix, true);
          File splitFile = new File(Globals.IMAGE_BASE_GALLERY_FOLDER() + "temp"
                  + x + "_" + y + "." + "jpg");
          fileList.add(splitFile);
  
          pieceOfBitmap.compress(Bitmap.CompressFormat.PNG, 0,
                  new FileOutputStream(splitFile, false));
          pieceOfBitmap.recycle();
      }
  </code></pre>