How to Rotate an Image in Android


While developing a new update for Android application (Notebook With Categories), we faced the following issue: when a user makes a photo (snapshot) under landscape mode, the app takes this picture in portrait under grid view which is not good for image preview. This error was not common, it occurred only on some devices. We managed to solve that issue via adding a Rotate Image button. We took some research and found out that there were no clear steps described by someone else explaining how to fix that, so here we are happy to share how we handled that. In short, this article will explain how to rotate a bitmap in Android. By the end, you will understand how to rotate the image in Java. One thing should be noted – due to a canvas restrictions, it is not really possible to rotate the image by an angle other than 90 degrees, not even 45.

Step 1. Create a new screen. The screen has a flat color background, Upload Image button and Rotate Image button (button which Rotates the image by 90 degrees). Rotate Image button will rotate Image on Button Click. By the button click, we imply the stroke into a center of the button.

Create MainActivity.xml

        android:layout_width=”fill_parent”         android:layout_height=”wrap_content”         android:layout_marginTop=”5dp”         android:orientation=”horizontal” >             android:layout_width=”match_parent”             android:layout_height=”wrap_content”             android:text=”Load Image”             android:id=”@+id/btn_loadImg”             android:layout_weight=”1″ />             android:id=”@+id/btn_RotateImg”             android:layout_width=”match_parent”             android:layout_height=”wrap_content”             android:layout_weight=”1″             android:text=”Rotate Image” />         android:id=”@+id/scrollView1″         android:layout_width=”match_parent”         android:layout_height=”wrap_content” >             android:layout_width=”match_parent”             android:layout_height=”match_parent”             android:layout_gravity=”center”             android:orientation=”vertical” >                 android:id=”@+id/imageView”                 android:layout_width=”wrap_content”                 android:layout_height=”wrap_content”                 android:layout_gravity=”center”                 android:background=”@drawable/ic_launcher” />

Step 2. Add permission to Manifest file for writing to external storage:

Step 3. Edit MainActivity.java file.

Add the function of the screen button for taking image from gallery:

public void loadBtnClick(View viev){ Intent intent = new Intent(); intent.setType(“image/*”); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, “Complete action using”), PICK_FROM_FILE); }

public void loadBtnClick(View viev){     Intent intent = new Intent();     intent.setType(“image/*”);     intent.setAction(Intent.ACTION_GET_CONTENT);     startActivityForResult(Intent.createChooser(intent, “Complete action using”), PICK_FROM_FILE);

Here we retrieve image path:

protected void onActivityResult (int requestCode,int resultCode,Intent data){ if (resultCode != RESULT_OK) return; String path = “”; if (requestCode == PICK_FROM_FILE) { Uri mImageCaptureUri = data.getData(); path = getRealPathFromURI (mImageCaptureUri); if (path == null) { path = mImageCaptureUri.getPath(); //from File Manager } Log.e(“path”, path); pathImage = path; imageView.setImageBitmap(getBitmap(path)) ; } }

protected void onActivityResult (int requestCode,int resultCode,Intent data){     if (resultCode != RESULT_OK) return;     if (requestCode == PICK_FROM_FILE) {             Uri mImageCaptureUri = data.getData();             path = getRealPathFromURI (mImageCaptureUri);                  path = mImageCaptureUri.getPath(); //from File Manager             imageView.setImageBitmap(getBitmap(path))  ;  

Let’s look at the screen size in order to make the image fit the screen size:

DisplayMetrics displaymetrics; displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); int screenWidth = displaymetrics.widthPixels; int screenHeight = displaymetrics.heightPixels;

DisplayMetrics displaymetrics; displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); int  screenWidth = displaymetrics.widthPixels; int screenHeight = displaymetrics.heightPixels;

Image processing to define image mode (landscape or portrait):

@SuppressLint(“NewApi”) private Bitmap getBitmap(String path) { Log.e(“inside of”, “getBitmap = “+path); try { Bitmap b = null; BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; Matrix matrix = new Matrix(); ExifInterface exifReader = new ExifInterface(path); int orientation = exifReader.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1); int rotate = 0; if (orientation ==ExifInterface.ORIENTATION_NORMAL) { // Do nothing. The original image is fine. } else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { rotate = 90; } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { rotate = 180; } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { rotate = 270; } matrix.postRotate(rotate); try { b = loadBitmap(path, rotate, screenWidth, screenHeight); btn_RotateImg.setEnabled(true); } catch (OutOfMemoryError e) { btn_RotateImg.setEnabled(false); } System.gc(); return b; } catch (Exception e) { Log.e(“my tag”, e.getMessage(), e); return null; } }

private Bitmap getBitmap(String path) { Log.e(“inside of”, “getBitmap = “+path); BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; Matrix matrix = new Matrix(); ExifInterface exifReader = new ExifInterface(path); int orientation = exifReader.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1); if (orientation ==ExifInterface.ORIENTATION_NORMAL) { // Do nothing. The original image is fine. } else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { matrix.postRotate(rotate);      b = loadBitmap(path, rotate, screenWidth, screenHeight); btn_RotateImg.setEnabled(true); } catch (OutOfMemoryError e) { btn_RotateImg.setEnabled(false); Log.e(“my tag”, e.getMessage(), e);

Insert the image from image file, set orientation and size of screen:

public static Bitmap loadBitmap(String path, int orientation, final int targetWidth, final int targetHeight) { Bitmap bitmap = null; try { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); int sourceWidth, sourceHeight; if (orientation == 90 || orientation == 270) { sourceWidth = options.outHeight; sourceHeight = options.outWidth; } else { sourceWidth = options.outWidth; sourceHeight = options.outHeight; } if (sourceWidth > targetWidth || sourceHeight > targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); options.inJustDecodeBounds = false; options.inSampleSize = (int)maxRatio; bitmap = BitmapFactory.decodeFile(path, options); } else { bitmap = BitmapFactory.decodeFile(path); } if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } sourceWidth = bitmap.getWidth(); sourceHeight = bitmap.getHeight(); if (sourceWidth != targetWidth || sourceHeight != targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); sourceWidth = (int)((float)sourceWidth / maxRatio); sourceHeight = (int)((float)sourceHeight / maxRatio); bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth, sourceHeight, true); } } catch (Exception e) { } return bitmap; }

public static Bitmap loadBitmap(String path, int orientation, final int targetWidth, final int targetHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); int sourceWidth, sourceHeight; if (orientation == 90 || orientation == 270) { sourceWidth = options.outHeight; sourceHeight = options.outWidth; sourceWidth = options.outWidth; sourceHeight = options.outHeight; if (sourceWidth > targetWidth || sourceHeight > targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); options.inJustDecodeBounds = false; options.inSampleSize = (int)maxRatio; bitmap = BitmapFactory.decodeFile(path, options); bitmap = BitmapFactory.decodeFile(path); Matrix matrix = new Matrix(); matrix.postRotate(orientation); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); sourceWidth = bitmap.getWidth(); sourceHeight = bitmap.getHeight(); if (sourceWidth != targetWidth || sourceHeight != targetHeight) { float widthRatio = (float)sourceWidth / (float)targetWidth; float heightRatio = (float)sourceHeight / (float)targetHeight; float maxRatio = Math.max(widthRatio, heightRatio); sourceWidth = (int)((float)sourceWidth / maxRatio); sourceHeight = (int)((float)sourceHeight / maxRatio); bitmap = Bitmap.createScaledBitmap(bitmap, sourceWidth, sourceHeight, true);

Set event function for Android rotate button:

public void rotateBtnclick(View viev){ rotateImage (pathImage); }

public void rotateBtnclick(View viev){

Look at the orientation of image and rotate the image for 90 degrees and then again upload it to ImageView:

public void rotateImage(String path){ File file = new File(path); ExifInterface exifInterface = null; try { exifInterface = new ExifInterface(file.getPath()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); if ( (orientation == ExifInterface.ORIENTATION_NORMAL) | (orientation == 0) ) { exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, “”+ExifInterface.ORIENTATION_ROTATE_90); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, “”+ExifInterface.ORIENTATION_ROTATE_180); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, “”+ExifInterface.ORIENTATION_ROTATE_270); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, “”+ExifInterface.ORIENTATION_NORMAL); } try { exifInterface.saveAttributes(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } imageView.setImageBitmap(getBitmap(path)) ; }

public void rotateImage(String path){ File file = new File(path); ExifInterface exifInterface = null; exifInterface = new ExifInterface(file.getPath()); } catch (IOException e) { // TODO Auto-generated catch block int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); if ( (orientation == ExifInterface.ORIENTATION_NORMAL) | (orientation == 0) ) { exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, “”+ExifInterface.ORIENTATION_ROTATE_90); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, “”+ExifInterface.ORIENTATION_ROTATE_180); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, “”+ExifInterface.ORIENTATION_ROTATE_270); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, “”+ExifInterface.ORIENTATION_NORMAL); exifInterface.saveAttributes(); } catch (IOException e) { // TODO Auto-generated catch block imageView.setImageBitmap(getBitmap(path))  ;

The repeated button presses will cyclically change the image orientation from 0 degrees to 90 degrees to 180 degrees to 270 degrees and to 0 degrees again. By the use of the RotateAnimation method, it is also possible to implement rotate animation.

Source code. Source code is available on github.

Read also:

• How to Choose a Mobile Development Platform?

• How Much Does It Cost to Develop a Mobile App?

• How to Integrate Payment Gateway in a Mobile App?

Rate:


Leave a Reply

Your email address will not be published. Required fields are marked *