I am trying to rotate large images taken by a phone camera (8 megapixels). Just Bitmap.createBitmap with the rotated matrix from the original bitmap is triggered in OutOfMemoryError. Thatโs why Iโm trying to split it into rotated parts and then combine them again into one rotating image to avoid storing 2 large bitmap images, but on my Samsung S3 it takes up to 10 seconds. Any other ways to do this?
public static void rotateImage(File file) throws FileNotFoundException { long time = System.currentTimeMillis(); List<File> fileList = new ArrayList<File>(); // 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 < rowsCols; y++) { int xCoord = 0; for (int x = 0; x < 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 < rowsCols; x++) { yCoord = 0; for (int y = 0; y < 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<File> 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<File> 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(); }