Rotate an image in Android without OutOfMemoryError or scaling

I am basically trying to rotate a Bitmap (from an image) in an Android application. The reason I want to do this is because the image taken from the camera (using the intent) is displayed horizontally even if it is captured vertically and the orientation is saved as metadata on the image. Correct me if you are mistaken. However, the problem is that when loading the image will take up a lot of memory if you take it on a phone with a good enough camera, and I did not find a way to rotate it and save it without getting an OutOfMemoryError. Below is the code where i:

  • Image upload
  • Check if you need to rotate it
  • Loads a smaller version for display in ImageView
  • Rotate a small image if necessary
  • In a separate topic; upload, rotate and save the image, so in the future it will not be needed

It is important that the application saves images in resolution, but any tricks with encodings are welcome. I searched the Internet for several days, unable to find anything more than what I have already implemented. There is another topic here, but there seem to be no solutions. Hope you can help.

public Bitmap getBitmap(final Context c) { if (bitmap != null) return bitmap; final int rotate = necessaryRotation(c, file); // if(rotate != 0) rotateImageFile(c, rotate); try { // Get scaled version BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(file, options); options.inSampleSize = calcInSampleSize(options, 1024, 1024); options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeFile(file, options); // rotate? bitmap = rotateImage(c,bitmap,rotate); System.out.println("Bitmap loaded from file: size=" + bitmap.getWidth() + "," + bitmap.getHeight()); System.gc(); } catch (Exception e) { System.err.println("Unable to load image file: " + this.getFilename()); } // if rotation is needed, do it in worker thread for next time if(rotate != 0){ Thread t = new Thread(new Runnable(){ public void run() { // load entire image try{ File imageFile = new File(getFilename()); Bitmap huge = Media.getBitmap(c.getContentResolver(), Uri.fromFile(imageFile)); huge = rotateImage(c,huge,rotate); // save bitmap properly FileOutputStream out = new FileOutputStream(imageFile); huge.compress(Bitmap.CompressFormat.PNG, 100, out); out.flush(); out.close(); huge.recycle(); huge = null; out = null; System.gc(); }catch(IOException e){ e.printStackTrace(); } } }); t.start(); } return bitmap; } private Bitmap rotateImage(Context c, Bitmap bitmap, int rotate) { if (rotate != 0) { // rotate Matrix m = new Matrix(); m.postRotate(rotate); Bitmap rotImage = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true); bitmap.recycle(); System.out.println("Image (id=" + getId() + ") rotated successfully"); System.gc(); return rotImage; } return bitmap; } private int necessaryRotation(Context c, String imageFile) { int rotate = 0; ExifInterface exif; try { exif = new ExifInterface(imageFile); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_270: rotate = 270; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate = 180; break; case ExifInterface.ORIENTATION_ROTATE_90: rotate = 90; break; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return rotate; } private int calcInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { int height = options.outHeight; int width = options.outWidth; int inSampleSize = 1; while (height > reqHeight || width > reqWidth) { height /= 2; width /= 2; inSampleSize *= 2; } return inSampleSize; } 

If there is something you need to know or any optimizations I can use to reduce memory usage, write :) Thanks

+6
source share
1 answer

Try this snippet:

 private Bitmap rotateImage(Context c, Bitmap bitmap, int rotate) { .... // reduce byte per pixel bitmap = bitmap.copy(Bitmap.Config.RGB_565, false); Bitmap.createBitmap(bitmap,... } 
0
source

Source: https://habr.com/ru/post/918693/


All Articles