Android: поворот изображения в imageview на угол

Я использую следующий код для поворота изображения в 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);

18 ответов


еще один простой способ повернуть ImageView:
обновление:
Необходимый импорт:

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

Код: (Если imageView, angle, pivotX & pivotY уже определены)

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

этот метод не требует создания нового растрового изображения каждый раз.

примечание: для поворота ImageView on ontouch во время выполнения вы можете set onTouchListener on ImageView & повернуть его, добавив последний два строки (т. е. postRotate матрицу и установить его на imageView) в приведенном выше коде раздел в вашем сенсорном прослушивателе ACTION_MOVE часть.


mImageView.setRotation(angle) с API>=11


Если вы поддерживаете API 11 или выше, вы можете просто использовать следующий атрибут XML:

android:rotation="90"

он может отображаться неправильно в Android Studio xml preview, но он работает так, как ожидалось.


есть два способа сделать это:

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 использовать RotateAnimation на View вы хотите повернуть, и убедитесь, что анимация для fillAfter=true, duration=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);

Я знаю, что это безумно поздно, но это было полезно для меня, так что это может помочь другим.

начиная с API 11, вы можете установить абсолютное вращение ImageView программно с помощью imageView.setRotation(angleInDegrees); метод.

по абсолюту, я имею в виду, что вы можете неоднократно вызывать эту функцию без необходимости отслеживать текущее вращение. То есть, если я вращаюсь, проходя 15F до setRotation() метод, а затем вызвать setRotation() снова 30F, вращение изображения с 30 градусами, не 45 градусов.

Примечание: это действительно работает для любого подкласса посмотреть объект, а не только ImageView.


Это мой реализация RotatableImageView. Использование очень просто: Просто скопируйте attrs.в XML и RotatableImageView.java в ваш проект и добавьте RotatableImageView в свой макет. Задайте угол поворота с помощью пример:угол


попробуйте это на пользовательском представлении

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


вот хорошее решение для размещения повернутого drawable для 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, которое я сделал здесь


просто напишите это в своем 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 невозможно при инициализации активности Для этого, пожалуйста, обратитесь к этому решение или установите размеры на 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, даже если это не необходимо(когда высота меньше ширины).Если это вас беспокоит, вы можете добавить еще один тернарный оператор внутри scaleX/scaleY.


Я думаю, что лучший способ :)

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

к сожалению, я не думаю, что есть. The Matrix класс отвечает за все манипуляции с изображениями, будь то вращение, сжатие/рост, перекос и т. д.

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

мои извинения, но я не могу придумать альтернативу. Может быть, кто-то другой и смог бы, но когда мне приходилось манипулировать образом, я использовал матрицу.

удачи!


другим возможным решением является создание собственного пользовательского представления изображения(скажем RotateableImageView extends ImageView )...и переопределите onDraw (), чтобы повернуть холст/растровые изображения перед повторным переходом на холст.Не забудьте восстановить холст.

но если вы собираетесь повернуть только один экземпляр изображения,ваше решение должно быть достаточно хорошим.


без матрицы и анимированные:

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

попробуйте этот код 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);

следуйте приведенному ниже ответу для непрерывного вращения imageview

int i=0;

Если кнопка поворота нажата

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