Android:将imageview中的图像旋转一个角度


154

我正在使用以下代码旋转ImageView中的图像一个角度。是否有任何更简单,更简单的方法可用。

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);

6
PS for 2014,看来您可以在Android Studio中的XML中简单地设置“旋转”。(如果您不习惯使用“文本”布局,甚至可以单击右侧的“专家属性”按钮!)
Fattie 2014年

Answers:


194

旋转ImageView
UPDATE的另一种简单方法
必需的导入:

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

代码:(假设imageViewanglepivotXpivotY已经定义)

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

此方法不需要每次都创建一个新的位图。

注意:要旋转ImageViewontouch在运行时可以设置onTouchListenerImageView和通过增加(即最后两行,将其旋转postRotate矩阵设置上的ImageView)在上面的代码段在您触摸听众ACTION_MOVE一部分。


109
为了完整起见,以下是基于ImageView的值的行:matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
Stefan Hoth

2
如何在每次触摸事件时旋转imageview?
索拉卜

14
对我来说,如果在relativeLayout中旋转,则imageView会增长到所包含图像的大小,不再适合布局。有人有解决此问题的经验吗?
Makibo

7
注意:要使此方法起作用,您必须设置您ImageViewsrc属性。getDrawable()在为我返回null之前,直到我意识到我设置了ImageViewbackground属性而不是srcfacepalm
Gary S.

1
它仅在imageview中旋转图像。我也应该怎么做才能旋转图像本身?
Ege

177

mImageView.setRotation(angle) 使用API​​> = 11


3
是否还会将视图的宽度和高度更改为正确的大小?还是仅改变外观?
Android开发人员

5
旋转时是否可以有“旋转动画”?
伊万·莫里约

13
@IvanMorgillo您可以看一下ViewPropertyAnimator,它的用法像aView.animate().rotation(20).start()
Jokester

5
@IvanMorgillo:使用rotationBy()。例如,view.animate().rotationBy(180f).start()。但是,如果连续单击该视图,则会出现问题。
Mangesh

我在按钮中使用此代码。第一次单击是可以的,但接下来的单击将不再旋转。我是否应该再改行来解决此问题?
Eggakin Baconwalker

73

如果您支持API 11或更高版本,则可以使用以下XML属性:

android:rotation="90"

它可能无法在Android Studio xml预览中正确显示,但可以正常工作。


3
关于XML预览的提示对我帮助很大
非淋菌性尿道炎

应用旋转后,XML预览正确显示给我。
迪克·卢卡斯

这将旋转视图,但不会旋转图像!这将在图像旁边添加空白区域。只需添加一个background即可看到效果。
YBrush

43

有两种方法可以做到这一点:

1 Matrix用于创建新的位图:

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使用RotateAnimationView要旋转,并确保动画设置为fillAfter=trueduration=0,和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"
/>

并在代码中添加动画:

Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotation);
myView.startAnimation(rotation);

danx ..但是是上真纽约方式做RotateAnimation上查看dynamically..i指接d角度动态..
rijinrv

如果您需要旋转的图像位于ListView中,则此方法会比公认的答案更好
Daren 2014年

9

我知道这太疯狂了,但这对我很有帮助,因此可能对其他人有帮助。

从API 11开始,您可以使用imageView.setRotation(angleInDegrees);方法以编程方式设置ImageView的绝对旋转。

绝对地说,我的意思是您可以重复调用此函数,而不必跟踪当前的旋转。意思是,如果我通过传递15FsetRotation()方法来旋转,然后使用setRotation()再次调用30F,则图像的旋转角度为30度,而不是45度。

注意:这实际上适用于View对象的任何子类,而不仅仅是ImageView。


我旋转时的图像在页面上自然会高一点。如何设置下来?
我想知道

您的图像是否正确居中?如果图像的透明度不均匀,则旋转时旋转可能会导致其看起来位置发生变化
thomaspsk

没有人,当图像旋转时,它使用轴。想象您的手机在手上处于垂直位置,现在将其旋转到水平位置。它不再碰你的手。所以有一个空间...但是我通过使用setPivotX()解决了这个问题
我想知道

5

这是我对RotatableImageView的实现。用法很简单:只要复制attrs.xmlRotatableImageView.java到您的项目,并添加RotatableImageView到您的布局。使用example:angle参数设置所需的旋转角度。

<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>

如果您在显示图像时遇到问题,请尝试在RotatableImageView.onDraw()方法中更改代码或改用draw()方法。


1
很有帮助。感谢分享!
Stefan Hoth 2012年

使用RotatableImageView时出现NullPointerException。受保护的void onMeasure(int widthMeasureSpec,int heightMeasureSpec){int w = getDrawable()。getIntrinsicWidth(); ...}顺便说一句,我在代码中使用了它(并具有给定的默认图像),而不是在xml中使用它。
RRTW

在gridView中使用此imageView时,出现了怪异的问题。在滚动之前,它一直不可见。
Android开发人员


3

另外,如果您想垂直或水平旋转ImageView 180度,可以使用scaleYscaleX属性并将其设置为-1f。这是一个Kotlin示例:

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

1f 值用于将ImageView返回其正常状态:

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

2

我对此有解决方案。实际上,它是旋转后出现的问题的解决方案(矩形图像不适合ImagView,但它也涵盖了您的问题。)尽管此解决方案具有“动画”的好坏

    int h,w;
    Boolean safe=true;

在活动初始​​化时无法获取imageView的参数。为此,请参考此解决方案 在按钮的onClick上设置尺寸。

    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 
       }

以及要旋转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();
        }
    });

这个解决方案足以解决上述问题。尽管即使不必要,它也会缩小imageView(当高度小于Width时)。如果麻烦,您可以在scaleX / scaleY内添加另一个三元运算符。


2

我认为最好的方法:)

int angle = 0;
imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            angle = angle + 90;
            imageView.setRotation(angle);
        }
    });

2

延迟旋转android中的图片:

imgSplash.animate().rotationBy(360f).setDuration(3000).setInterpolator(new LinearInterpolator()).start();

1

在自定义视图上尝试

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);
    }
}


1

这是为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;
}

用法:

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

另一种选择:

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();
        }
    };
}

另外,如果您希望旋转位图,但又害怕OOM,则可以使用我在此处制作的NDK解决方案


1

如果只想视觉旋转视图,则可以使用:

iv.setRotation(float)

1

对于科特林,

mImageView.rotation = 90f //angle in float

这将旋转imageView而不是旋转图像

另外,尽管它是View类中的一个方法。因此,您几乎可以使用它旋转任何视图。



0

另一种可能的解决方案是创建自己的自定义Image视图(例如RotateableImageView extends ImageView)...,并覆盖onDraw()以便在重新加载到画布上之前旋转画布/位图。不要忘记将画布恢复原状。

但是,如果仅旋转图像视图的单个实例,则您的解决方案应该足够好。


0

没有矩阵和动画:

{
    img_view = (ImageView) findViewById(R.id.imageView);
    rotate = new RotateAnimation(0 ,300);
    rotate.setDuration(500);
    img_view.startAnimation(rotate);
}

0

只需将其写在您的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); 

0

尝试此代码100%有效;

在旋转按钮上单击,请编写以下代码:

        @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);
            }
        }

0

而不是将图像转换为位图然后旋转,请尝试旋转直接图像视图,如以下代码所示。

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);

0

请按照以下答案连续旋转imageview

int i=0;

如果单击旋转按钮

imageView.setRotation(i+90);
i=i+90;

0

如果您想将图像旋转180度,则将这两个值放在imageview标签中:

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

说明:-scaleX = 1和scaleY = 1代表正常状态​​,但如果我们在scaleX / scaleY属性上放置-1,则它将旋转180度


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);

如何使用?

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);
   }
}

0

您可以简单地使用ImageView的旋转属性

以下是ImageView的属性,其中包含Android来源的详细信息

<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.