Android: Rotate image in imageview by an angle
Asked Answered
N

28

191

I am using the following code to rotate a image in ImageView by an angle. Is there any simpler and less complex method available.

ImageView iv = (ImageView)findViewById(imageviewid);
TextView tv = (TextView)findViewById(txtViewsid);
Matrix mat = new Matrix();
Bitmap bMap = BitmapFactory.decodeResource(getResources(),imageid);
mat.postRotate(Integer.parseInt(degree));===>angle to be rotated
Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0,bMap.getWidth(),bMap.getHeight(), mat, true);
iv.setImageBitmap(bMapRotate);
Nastassia answered 24/1, 2012 at 4:0 Comment(2)
PS for 2014, it looks like you can simply set "rotation" in the XML in Android Studio. (You can even just click the "expert properties" button on the right, if you can't be bothered using the 'Text' layout!)Collegium
find answer right here. https://mcmap.net/q/109603/-how-to-make-a-smooth-image-rotation-in-androidDannettedanni
M
207

Another simple way to rotate an ImageView:
UPDATE:
Required imports:

import android.graphics.Matrix;
import android.widget.ImageView;

Code: (Assuming imageView, angle, pivotX & pivotY are already defined)

Matrix matrix = new Matrix();
imageView.setScaleType(ImageView.ScaleType.MATRIX);   //required
matrix.postRotate((float) angle, pivotX, pivotY);
imageView.setImageMatrix(matrix);

This method does not require creating a new bitmap each time.

NOTE: To rotate an ImageView on ontouch at runtime you can set onTouchListener on ImageView & rotate it by adding last two lines(i.e. postRotate matrix & set it on imageView) in above code section in your touch listener ACTION_MOVE part.

Moneybag answered 11/4, 2012 at 10:37 Comment(15)
For completeness here is the line based on the ImageView's values: matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);Eddi
how to rotate imageview on every touch event?Fantastic
for me, if rotated in a relativeLayout the imageView grows to the size of the image contained, not fitting into the layout anymore. Does anybody have experience how to solve this?Pudgy
Note: for this to work, you have to set your ImageView's src attribute. getDrawable() was returning null for me until I realized that I had set the ImageView's background attribute instead of src. facepalmBoatload
@StefanHoth if i already have the bitmap, i can just use the width and the height of it, right?Skivvy
@androiddeveloper Yes, that should work as long it's the same bitmap regarding size.Eddi
@StefanHoth what if I want to do both rotation and then center-crop on the imageView ? can you please help me out on this? I've made a post here: #20949473 . the reason I need to rotate is described there.Skivvy
It rotates the image in imageview only. What should I do to rotate the image itself too?Whenas
@StefanHoth what about if i use imageView.getWidth() / 2?Spiegel
@Pudgy Hi, did you find some solution to it?Acatalectic
which imports do i have to add for this to work? Almost everything is red. Also, it says new matrix() is depriciated.Systematics
I did this on in onConfigurationChanged but it is not working any idea? I am trying to rotate image when screen orientation changesAmphetamine
@Pudgy yes, the image size is changing after rotation (because it is a rectangle). If you display it with the same coordinates (upper left corner), it looks shifted. Yet, you can adjust it: X -= ( img.getWidth() - originalImgageWidth ) / 2;Margetts
BTW you can get the pivotX/Y by calling imageView.getPivotX/YRosetta
https://mcmap.net/q/134514/-android-rotate-image-in-imageview-by-an-angleHolozoic
E
223

mImageView.setRotation(angle) with API>=11

Extremism answered 24/1, 2013 at 19:39 Comment(7)
would it also change the width and height of the view to the correct size ? or does it change only how it looks?Skivvy
Is there a way to have a "rotation animation" while rotating?Trevethick
@IvanMorgillo You can have a look at ViewPropertyAnimator, which is used like aView.animate().rotation(20).start()Risky
@IvanMorgillo: Use rotationBy(). For example, view.animate().rotationBy(180f).start(). But it becomes problematic if the view is clicked successively.Autotruck
I'm using this code in a button. The first click is ok, But the next clicks doesn't rotate anymore. Should I put some other line to fix this?Moskowitz
it reverses the height and width of image view.Atmo
https://mcmap.net/q/134514/-android-rotate-image-in-imageview-by-an-angleHolozoic
M
207

Another simple way to rotate an ImageView:
UPDATE:
Required imports:

import android.graphics.Matrix;
import android.widget.ImageView;

Code: (Assuming imageView, angle, pivotX & pivotY are already defined)

Matrix matrix = new Matrix();
imageView.setScaleType(ImageView.ScaleType.MATRIX);   //required
matrix.postRotate((float) angle, pivotX, pivotY);
imageView.setImageMatrix(matrix);

This method does not require creating a new bitmap each time.

NOTE: To rotate an ImageView on ontouch at runtime you can set onTouchListener on ImageView & rotate it by adding last two lines(i.e. postRotate matrix & set it on imageView) in above code section in your touch listener ACTION_MOVE part.

Moneybag answered 11/4, 2012 at 10:37 Comment(15)
For completeness here is the line based on the ImageView's values: matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);Eddi
how to rotate imageview on every touch event?Fantastic
for me, if rotated in a relativeLayout the imageView grows to the size of the image contained, not fitting into the layout anymore. Does anybody have experience how to solve this?Pudgy
Note: for this to work, you have to set your ImageView's src attribute. getDrawable() was returning null for me until I realized that I had set the ImageView's background attribute instead of src. facepalmBoatload
@StefanHoth if i already have the bitmap, i can just use the width and the height of it, right?Skivvy
@androiddeveloper Yes, that should work as long it's the same bitmap regarding size.Eddi
@StefanHoth what if I want to do both rotation and then center-crop on the imageView ? can you please help me out on this? I've made a post here: #20949473 . the reason I need to rotate is described there.Skivvy
It rotates the image in imageview only. What should I do to rotate the image itself too?Whenas
@StefanHoth what about if i use imageView.getWidth() / 2?Spiegel
@Pudgy Hi, did you find some solution to it?Acatalectic
which imports do i have to add for this to work? Almost everything is red. Also, it says new matrix() is depriciated.Systematics
I did this on in onConfigurationChanged but it is not working any idea? I am trying to rotate image when screen orientation changesAmphetamine
@Pudgy yes, the image size is changing after rotation (because it is a rectangle). If you display it with the same coordinates (upper left corner), it looks shifted. Yet, you can adjust it: X -= ( img.getWidth() - originalImgageWidth ) / 2;Margetts
BTW you can get the pivotX/Y by calling imageView.getPivotX/YRosetta
https://mcmap.net/q/134514/-android-rotate-image-in-imageview-by-an-angleHolozoic
C
107

If you're supporting API 11 or higher, you can just use the following XML attribute:

android:rotation="90"

It might not display correctly in Android Studio xml preview, but it works as expected.

Cnidus answered 10/10, 2014 at 16:26 Comment(4)
The hint regarding the xml preview helped me a lotFoy
The XML preview is displaying for me properly after rotation is applied.Francisco
This will rotate the view but not the image! This will add blank areas beside the image. Just add a background to see the effect.Fireguard
https://mcmap.net/q/134514/-android-rotate-image-in-imageview-by-an-angleHolozoic
P
47

There are two ways to do that:

1 Using Matrix to create a new bitmap:

imageView = (ImageView) findViewById(R.id.imageView);
Bitmap myImg = BitmapFactory.decodeResource(getResources(), R.drawable.image);

Matrix matrix = new Matrix();
matrix.postRotate(30);

Bitmap rotated = Bitmap.createBitmap(myImg, 0, 0, myImg.getWidth(), myImg.getHeight(),
        matrix, true);

imageView.setImageBitmap(rotated);

2 use RotateAnimation on the View you want to Rotate, and make sure the Animation set to fillAfter=true, duration=0, and fromDegrees=toDgrees

 <?xml version="1.0" encoding="utf-8"?>
<rotate
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromDegrees="45"
  android:toDegrees="45"
  android:pivotX="50%"
  android:pivotY="50%"
  android:duration="0"
  android:startOffset="0"
/>

and Inflate the Animation in code:

Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotation);
myView.startAnimation(rotation);
Plebs answered 25/1, 2012 at 0:56 Comment(3)
danx.. But is dere ny way to do RotateAnimation on the View dynamically..i mean to set d angle dynamically..Nastassia
this works better than the accepted answer if the image you need to rotate is in a ListViewMia
@Nastassia Animation rotateAnimation = new RotateAnimation(currentRotation, currentRotation -= 90, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); rotateAnimation.setDuration(100); rotateAnimation.setFillAfter(true); photoView.startAnimation(rotateAnimation);Holozoic
M
11

I know this is insanely late, but it was helpful for me so it may help others.

As of API 11, you can set the absolute rotation of an ImageView programmatically by using the imageView.setRotation(angleInDegrees); method.

By absolute, I mean you can repeatedly call this function without having to keep track of the current rotation. Meaning, if I rotate by passing 15F to the setRotation() method, and then call setRotation() again with 30F, the image's rotation with be 30 degrees, not 45 degrees.

Note: This actually works for any subclass of the View object, not just ImageView.

Mcalpine answered 25/10, 2016 at 16:14 Comment(3)
My image at rotating gets naturally a little bit higher on the page. How can I set it down?Smallsword
Is your image centered properly? If you have an uneven amount of transparency in your image, rotation can cause it to appear to change position when rotatingMcalpine
No man, when image rotates it uses the axis. Imagine your cellphone in vertical position on your hand, now rotate it to horizontal. It doesn't touch your hand any more. So there's a space... But I solved it by using setPivotX()Smallsword
S
10

For Kotlin,

mImageView.rotation = 90f //angle in float

This will rotate the imageView rather than rotating the image

Also, though its a method in View class. So you can pretty much rotate any view using it.

Subulate answered 9/12, 2019 at 8:48 Comment(0)
F
7

Can also be done this way:-

imageView.animate().rotation(180).start();

got from here.

Fractional answered 27/10, 2018 at 17:22 Comment(2)
Thanks! It's very easy and quickSeville
can we set an anchor too? I'm planning not giving the animation but the drag effect for rotating with an anchor,... if that's possible? @DebasishYokefellow
M
7

Rotate an image in android with delay:

imgSplash.animate().rotationBy(360f).setDuration(3000).setInterpolator(new LinearInterpolator()).start();
Marchland answered 17/4, 2019 at 8:23 Comment(0)
S
5

This is my implementation of RotatableImageView. Usage is very easy: just copy attrs.xml and RotatableImageView.java into your project and add RotatableImageView to your layout. Set desired rotation angle using example:angle parameter.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:example="http://schemas.android.com/apk/res/com.example"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.example.views.RotatableImageView
        android:id="@+id/layout_example_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:src="@drawable/ic_layout_arrow"
        example:angle="180" />
</FrameLayout>

If you have some problems with displaying image, try change code in RotatableImageView.onDraw() method or use draw() method instead.

Swahili answered 27/8, 2012 at 8:55 Comment(2)
I got a NullPointerException while using RotatableImageView. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int w=getDrawable().getIntrinsicWidth(); ... } BTW, I was use it in code(and have a given default image), not in xml.Pharmaceutics
this imageView has weird issues when being used in a gridView. it keeps getting invisible till you scroll.Skivvy
C
4

Also, if you want to rotate an ImageView by 180 degrees vertically or horizontally, you can use scaleY or scaleX properties and set them to -1f. Here is a Kotlin example:

imageView.scaleY = -1f
imageView.scaleX = -1f

1f value is used to return an ImageView to its normal state:

imageView.scaleY = 1f
imageView.scaleX = 1f
Cajolery answered 20/12, 2018 at 4:51 Comment(1)
How to rotate 90 degree?Hebbel
D
3

I have a solution to this. Actually it is a solution to a problem that arises after rotation(Rectangular image doesn't fit ImagView) but it covers your problem too.. Although this Solution has Animation for better or for worse

    int h,w;
    Boolean safe=true;

Getting the parameters of imageView is not possible at initialisation of activity To do so please refer to this solution OR set the dimensions at onClick of a Button Like this

    rotateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(imageView.getRotation()/90%2==0){
                h=imageView.getHeight();
                w=imageView.getWidth();

            }
        .
        .//Insert the code Snippet below here 
       }

And the code to be run when we want to rotate ImageView

if(safe)     
imageView.animate().rotationBy(90).scaleX(imageView.getRotation()/90%2==0?(w*1.0f/h):1).scaleY(imageView.getRotation()/90%2==0?(w*1.0f/h):1).setDuration(2000).setInterpolator(new LinearInterpolator()).setListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
                      safe=false;
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                      safe=true;

                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            }).start();
        }
    });

This solution is sufficient for the Problem above.Although it will shrink the imageView even if it is not necessary(when height is smaller than Width).If it bothers you,you can add another ternary operator inside scaleX/scaleY.

Debutant answered 25/12, 2017 at 16:36 Comment(0)
M
3

I think the best method :)

int angle = 0;
imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            angle = angle + 90;
            imageView.setRotation(angle);
        }
    });
Mufi answered 29/8, 2018 at 11:57 Comment(1)
can we set anchor while rotating?Yokefellow
C
3

You can simply use rotation atribute of ImageView

Below is the attribute from ImageView with details from Android source

<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />
Condon answered 20/6, 2020 at 17:20 Comment(0)
S
2

here's a nice solution for putting a rotated drawable for an imageView:

Drawable getRotateDrawable(final Bitmap b, final float angle) {
    final BitmapDrawable drawable = new BitmapDrawable(getResources(), b) {
        @Override
        public void draw(final Canvas canvas) {
            canvas.save();
            canvas.rotate(angle, b.getWidth() / 2, b.getHeight() / 2);
            super.draw(canvas);
            canvas.restore();
        }
    };
    return drawable;
}

usage:

Bitmap b=...
float angle=...
final Drawable rotatedDrawable = getRotateDrawable(b,angle);
root.setImageDrawable(rotatedDrawable);

another alternative:

private Drawable getRotateDrawable(final Drawable d, final float angle) {
    final Drawable[] arD = { d };
    return new LayerDrawable(arD) {
        @Override
        public void draw(final Canvas canvas) {
            canvas.save();
            canvas.rotate(angle, d.getBounds().width() / 2, d.getBounds().height() / 2);
            super.draw(canvas);
            canvas.restore();
        }
    };
}

also, if you wish to rotate the bitmap, but afraid of OOM, you can use an NDK solution i've made here

Skivvy answered 27/1, 2014 at 8:28 Comment(0)
L
2

It is too late for the answer, someone may found this useful, I came across a situation where I need to animate the rotation og ImageView by some angle on first ClickListener event, and then on the 2nd ClickListener event, need to rotate back the image to the original angle. this is how this magic happened

fun rotateAnim(imageView: ImageView,angle : Float){
    imageView.isEnabled = false
    Log.i(TAG, "onCreate: ${imageView.rotation}")
    val rotation = imageView.animate().rotationBy(angle)
    rotation.interpolator = FastOutSlowInInterpolator()
    rotation.startDelay = 200
    rotation.setListener(object : Animator.AnimatorListener{
        override fun onAnimationEnd(animation: Animator?) {
           imageView.isEnabled = true
        }
        override fun onAnimationStart(animation: Animator?) {}
        override fun onAnimationCancel(animation: Animator?) {}
        override fun onAnimationRepeat(animation: Animator?) {}

    })
    rotation.start()
}

and implementation is like

holder.itemView.setOnClickListener {
    val rotation = imageView.rotation
    if(rotation == 180F){
         rotateAnim(imageView,90F)
    }else{
         rotateAnim(imageView,-90F)
    }
}
Lindholm answered 25/3, 2022 at 10:41 Comment(0)
S
1

Sadly, I don't think there is. The Matrix class is responsible for all image manipulations, whether it's rotating, shrinking/growing, skewing, etc.

http://developer.android.com/reference/android/graphics/Matrix.html

My apologies, but I can't think of an alternative. Maybe someone else might be able to, but the times I've had to manipulate an image I've used a Matrix.

Best of luck!

Simplex answered 25/1, 2012 at 0:18 Comment(0)
T
1

try this on a custom view

public class DrawView extends View {


    public DrawView(Context context,AttributeSet attributeSet){
        super(context, attributeSet);
    }

    @Override
    public void onDraw(Canvas canvas) {
        /*Canvas c=new Canvas(BitmapFactory.decodeResource(getResources(), R.drawable.new_minute1)    );

        c.rotate(45);*/

        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.new_minute1), 0, 0, null);
        canvas.rotate(45);
    }
}

Turncoat answered 21/12, 2012 at 11:4 Comment(0)
B
1

If you only want to rotate the view visually you can use:

iv.setRotation(float)
Barrens answered 8/2, 2018 at 15:42 Comment(0)
S
1

if u want to rotate an image by 180 degrees then put these two value in imageview tag:-

android:scaleX="-1"
android:scaleY="-1"

Explanation:- scaleX = 1 and scaleY = 1 repesent it's normal state but if we put -1 on scaleX/scaleY property then it will be rotated by 180 degrees

Syrian answered 5/8, 2019 at 15:38 Comment(0)
F
1

Using Kotlin:

imageView.rotation = degrees.toFloat()
Finer answered 22/12, 2022 at 11:4 Comment(0)
B
0

Another possible solution is to create your own custom Image view(say RotateableImageView extends ImageView )...and override the onDraw() to rotate either the canvas/bitmaps before redering on to the canvas.Don't forget to restore the canvas back.

But if you are going to rotate only a single instance of image view,your solution should be good enough.

Blaze answered 25/1, 2012 at 0:27 Comment(0)
L
0

without matrix and animated:

{
    img_view = (ImageView) findViewById(R.id.imageView);
    rotate = new RotateAnimation(0 ,300);
    rotate.setDuration(500);
    img_view.startAnimation(rotate);
}
Langmuir answered 9/4, 2015 at 21:37 Comment(0)
C
0

just write this in your onactivityResult

            Bitmap yourSelectedImage= BitmapFactory.decodeFile(filePath);
            Matrix mat = new Matrix();
            mat.postRotate((270)); //degree how much you rotate i rotate 270
            Bitmap bMapRotate=Bitmap.createBitmap(yourSelectedImage, 0,0,yourSelectedImage.getWidth(),yourSelectedImage.getHeight(), mat, true);
            image.setImageBitmap(bMapRotate);
            Drawable d=new BitmapDrawable(yourSelectedImage);
            image.setBackground(d); 
Choe answered 9/2, 2017 at 4:5 Comment(0)
E
0

Try this code 100% working;

On rotate button click write this code:

        @Override
        public void onClick(View view) {
            if(bitmap==null){
                Toast.makeText(getApplicationContext(), "Image photo is not yet set", Toast.LENGTH_LONG).show();
            }
            else {
                Matrix matrix = new Matrix();
                ivImageProduct.setScaleType(ImageView.ScaleType.MATRIX);   //required
                matrix.postRotate(90,ivImageProduct.getDrawable().getBounds().width()/2,ivImageProduct.getDrawable().getBounds().height()/2);
                Bitmap bmp=Bitmap.createBitmap(bitmap, 0, 0,bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                bitmap.recycle();
                bitmap=bmp;
                ivImageProduct.setImageBitmap(bitmap);
            }
        }
Extravagance answered 21/1, 2018 at 7:57 Comment(0)
C
0

Rather than convert image to bitmap and then rotate it try to rotate direct image view like below code.

ImageView myImageView = (ImageView)findViewById(R.id.my_imageview);

AnimationSet animSet = new AnimationSet(true);
animSet.setInterpolator(new DecelerateInterpolator());
animSet.setFillAfter(true);
animSet.setFillEnabled(true);

final RotateAnimation animRotate = new RotateAnimation(0.0f, -90.0f,
    RotateAnimation.RELATIVE_TO_SELF, 0.5f, 
    RotateAnimation.RELATIVE_TO_SELF, 0.5f);

animRotate.setDuration(1500);
animRotate.setFillAfter(true);
animSet.addAnimation(animRotate);

myImageView.startAnimation(animSet);
Congreve answered 22/5, 2018 at 11:51 Comment(0)
C
0

Follow the below answer for continuous rotation of an imageview

int i=0;

If rotate button clicked

imageView.setRotation(i+90);
i=i+90;
Colan answered 12/8, 2018 at 5:5 Comment(0)
I
0
Matrix matrix = new Matrix();
imageView.setScaleType(ImageView.ScaleType.MATRIX); //required
matrix.postRotate((float) 20, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
imageView.setImageMatrix(matrix);

how to use?

public class MainActivity extends AppCompatActivity {
   int view = R.layout.activity_main;
   TextView textChanger;
   ImageView imageView;
   @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(view);
      textChanger = findViewById(R.id.textChanger);
      imageView=findViewById(R.id.imageView);
      textChanger.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            roateImage(imageView);
         }
      });
   }
   private void roateImage(ImageView imageView) {
      Matrix matrix = new Matrix();
      imageView.setScaleType(ImageView.ScaleType.MATRIX); //required
      matrix.postRotate((float) 20, imageView.getDrawable().getBounds().width()/2,    imageView.getDrawable().getBounds().height()/2);
      imageView.setImageMatrix(matrix);
   }
}
Incest answered 11/8, 2019 at 13:33 Comment(0)
H
0

I added several solution. If you want to rotate image on click btn and image size must be fill parent layout. You can also use https://github.com/rongi/rotate-layout and https://mcmap.net/q/136755/-android-imageview-rotation-animation-keep-scale-type-fit-center this code also works

        ImageView photoView = findViewById(R.id.photo_view);
        ImageView rotateBtn = findViewById(R.id.rotate_image);
        FrameLayout photoFrame = dialogView.findViewById(R.id.photoFrame);

        final float[] currentRotation = {0f};
        final boolean[] isFirst = {true};
        final boolean[] isInitial = {true};
        final float[] firstWidth = {0};
        final float[] firstHeight = {0};
        final float[] secondWidth = {0};
        final float[] secondHeight = {0};

        rotate_image.setOnClickListener(view -> {
            if (isInitial[0]) {
                isInitial[0] = false;

                firstWidth[0] = photoView.getWidth();
                firstHeight[0] = photoView.getHeight();

                float frameWidth = photoFrame.getWidth();
                float frameHeight = photoFrame.getHeight();

                if (firstHeight[0] >= firstWidth[0]) {
                    float imageRatio = firstHeight[0] / firstWidth[0];
                    if (frameHeight > frameWidth) {
                        secondWidth[0] = frameWidth;
                        secondHeight[0] = secondWidth[0] / imageRatio;
                    } else {
                        secondHeight[0] = frameHeight;
                        secondWidth[0] = secondHeight[0] * imageRatio;
                    }
                } else {
                    float imageRatio = firstWidth[0] / firstHeight[0];
                    float frameRatio = frameHeight / frameWidth;
                    if (imageRatio >= frameRatio) {
                        secondHeight[0] = frameHeight;
                        secondWidth[0] = secondHeight[0] / imageRatio;
                    } else {
                        secondWidth[0] = frameWidth;
                        secondHeight[0] = secondWidth[0] * imageRatio;
                    }
                }
            }

            float imageWidth = isFirst[0] ? secondWidth[0] : firstHeight[0];
            float imageHeight = isFirst[0] ? secondHeight[0] : firstWidth[0];
            
            isFirst[0] = !isFirst[0];
        // You can use custom animation
        //Animation rotateAnimation = new RotateAnimation(currentRotation, 
        //currentRotation -= 90, Animation.RELATIVE_TO_SELF, 0.5f, 
        //Animation.RELATIVE_TO_SELF, 0.5f);
        //rotateAnimation.setDuration(100);
        //rotateAnimation.setFillAfter(true);
        //photoView.startAnimation(rotateAnimation);

            photoView.animate().rotation(currentRotation[0] -= 90).start();
            photoView.getLayoutParams().height = (int) imageWidth;
            photoView.getLayoutParams().width = (int) imageHeight;
            photoView.requestLayout();
        });

My xml code below:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <FrameLayout
      android:id="@+id/photoFrame"
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:layout_marginVertical="10dp"
      app:layout_constraintBottom_toTopOf="@+id/rotate_image"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" >

      <ImageView
          android:id="@+id/photo_view"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_gravity="center"
          android:adjustViewBounds="true"
          android:scaleType="fitCenter"
          android:src="@mipmap/ic_client_photo_nophoto" />
  </FrameLayout>

    <ImageView
        android:id="@+id/rotate_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/rotate_image"
        android:layout_marginBottom="10dp"

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

I maked another solution without animation and it worked with image file:

    ImageView photoView = findViewById(R.id.photo_view);
    ImageView rotate_image = findViewById(R.id.rotate_image);

    Glide.with(context)
            .load(file)
            .diskCacheStrategy(DiskCacheStrategy.NONE)
            .skipMemoryCache(true)
            .into(photoView);
    
    rotate_image.setOnClickListener(view -> {
        rotateImageFile(file.getPath());
        Glide.with(context)
                .load(file)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .skipMemoryCache(true)
                .into(photoView);

    });

public void rotateImageFile(String imagePath) {
    try {
        ExifInterface exif = new ExifInterface(imagePath);
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);

        switch (orientation) {
            case 1:
                exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_90));
                break;
            case 6:
                exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_180));
                break;
            case 3:
                exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_270));
                break;
            case 8:
                exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_NORMAL));
                break;
        }
        exif.saveAttributes();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Another solution works with Bitmap but without animation, quality can decrease and rotate can be not smoothly, test it.

ImageView photoView = findViewById(R.id.photo_view);
ImageView rotate_image = findViewById(R.id.rotate_image);
final Bitmap[] bitmap = {BitmapFactory.decodeFile(file.getPath())};
//If you dont use file add this code inside of setOnClickListener
//bitmap[0] =((BitmapDrawable) photoView.getDrawable()).getBitmap();

    rotate_image.setOnClickListener(view -> {
    //bitmap[0] =((BitmapDrawable) photoView.getDrawable()).getBitmap();
    Matrix matrix = new Matrix();
    matrix.postRotate(90);
    bitmap[0] = Bitmap.createBitmap(bitmap[0], 0, 0, bitmap[0].getWidth(), bitmap[0].getHeight(), matrix, true);
    photoView.setImageBitmap(bitmap[0]);
});

I added link address above and it is example code:

    ImageView photoView = findViewById(R.id.photo_view);
    ImageView rotate_image = findViewById(R.id.rotate_image);

        rotate_image.setOnClickListener(view -> {
        float scale = photoView.getRotation() % 180 == 0 ? (float) photoView.getWidth() / photoView.getHeight() : 1.0f;
        photoView.animate().rotationBy(90).scaleX(scale).scaleY(scale).setDuration(100).start();
    });
Holozoic answered 1/11, 2023 at 11:58 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.