Android: 通过一个角度在图像视图中旋转图像

我正在使用以下代码在 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);
368058 次浏览

很遗憾,我不这么认为。Matrix类负责所有的图像处理,无论是旋转、收缩/生长、倾斜等。

Http://developer.android.com/reference/android/graphics/matrix.html

我很抱歉,但我想不出别的办法。也许别人能做到,但我操纵图像的时候,我用的是 Matrix。

祝你好运!

另一个可能的解决方案是创建您自己的自定义 Image 视图(比如 RotateableImageView extends ImageView) ... 并覆盖 onDraw () ,在重新绘制到画布之前旋转画布/位图。别忘了把画布还原。

但是如果你只旋转图像视图的一个实例,你的解决方案应该是足够好的。

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

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

在你想旋转的 View上使用 RotateAnimation,并确保动画设置为 fillAfter=trueduration=0fromDegrees=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);

另一种旋转 ImageView的简单方法:
更新:
所需进口:

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

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

注意: 要在运行时在 接触上旋转 ImageView,您可以 在 ImageView上设置 OnTouchListener,并通过加入最后两个旋转它 行(即 后旋转矩阵并将其设置为 图片查看) 部分在您的触摸收听器 行动部分。

这是我的 旋转图像视图的实现。使用非常简单: 只需将 Xml可旋转的 ImageView.java复制到您的项目中,然后将 RotatableImageView 添加到您的布局中。使用 角度参数设置所需的旋转角度。

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

如果您在显示图像时遇到一些问题,请尝试在 可旋转图像视图方法中更改代码,或者使用 pull ()方法。

在自定义视图上试试这个

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

API > = 11的 mImageView.setRotation(angle)

这里有一个很好的解决方案,可以为 image 视图放置一个可旋转的绘图工具:

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 解决方案我已经做了 这里

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

android:rotation="90"

它可能不会在 AndroidStudioxml 预览中正确显示,但是它会按预期工作。

没有矩阵和动画:

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

我知道这太迟了,但这对我很有帮助,也许能帮到其他人。

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

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

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

把这个写在 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);

我对这个有 解决方案。 实际上,这是一个解决旋转后出现的问题(矩形图像不适合 ImagView) 但也能解决你的问题。 尽管这个解决方案有更好或更坏的动画

    int h,w;
Boolean safe=true;

在活动的初始化阶段不可能获得 imageView 的参数 这样做请参考此 解决方案 设置按钮上的尺寸,如下所示

    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,即使它不是必需的(当高度小于宽度时)。如果您感到困扰,可以在 scaleX/scaleY 中添加另一个三元运算符。

尝试此代码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);
}
}

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

iv.setRotation(float)

而不是转换图像位图,然后旋转它尝试旋转直接图像视图,如下面的代码。

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

按照下面的答案连续旋转一个图像视图

int i=0;

如果单击旋转按钮

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

我认为最好的方法是:)

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

也可以这样做:-

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

离开这里。

此外,如果您想通过 180度垂直或水平旋转 ImageView,可以使用 scaleYscaleX属性并将它们设置为 -1f。这里有一个科特林的例子:

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

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

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

延迟旋转机器人中的图像:

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

如果你想旋转一个图像180度,然后把这两个值在 image view 标签:-

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

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

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

为了科特林,

mImageView.rotation = 90f //angle in float

这将旋转 image View 而不是旋转图像

同样,虽然它是 View类中的一个方法,但是你可以使用它来旋转任何视图。

您可以简单地使用 ImageView 的 轮换属性

下面是来自 ImageView 的属性以及来自 Android 源代码的详细信息

<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />

现在回答已经太晚了,有人可能会发现这个有用,我遇到了一个情况,我需要动画的旋转 og ImageView由一些 angle在第一个 ClickListener事件,然后在第二个 ClickListener事件,需要 rotate回到原来的角度的图像。魔法就是这样发生的

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

执行就像

holder.itemView.setOnClickListener {
val rotation = imageView.rotation
if(rotation == 180F){
rotateAnim(imageView,90F)
}else{
rotateAnim(imageView,-90F)
}
}