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


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 на 2014 год, похоже, вы можете просто установить «вращение» в XML в Android Studio. (Вы даже можете просто нажать кнопку «Свойства эксперта» справа, если вас не беспокоит использование макета «Текст»!)
— Толстяк

найти ответ прямо здесь. stackoverflow.com/a/52983423/5872337
— Geet Thakur

Ответы:


194

Еще один простой способ поворота 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на ontouch во время выполнения вы можете установить onTouchListener на ImageView& вращать его, добавив две последние строки (т.е. postRotate матрицы и установить его на ImageView ) в выше разделе кода в вашем сенсорным слушателем ACTION_MOVE части.


109
Для полноты здесь есть линия , основываясь на ImageViewзначениях «S:matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
— Стефан Хота

2
Как повернуть изображение на каждом сенсорном событии?
— Саураб

14
для меня, если повернуть в относительной компоновке, imageView увеличивается до размера содержащегося изображения, больше не вписываясь в макет. У кого-нибудь есть опыт, как это решить?
— Макибо

7
Примечание: для этого на работу, вы должны установить ваш ImageView«S srcатрибут. getDrawable()возвращался нуль для меня , пока я не понял , что я поставил на ImageView«S backgroundатрибут вместо src. лицевая сторона
— Гэри С.

1
Поворачивает изображение только в режиме просмотра изображений. Что я должен сделать, чтобы повернуть само изображение?
— Ege

178

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(). Но это становится проблематичным, если на представление нажимают последовательно.
— Мангеш,

Я использую этот код в кнопке. Первый щелчок в порядке, но следующие щелчки больше не вращаются. Должен ли я поставить какую-то другую строку, чтобы исправить это?
— Eggakin Baconwalker

73

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

android:rotation="90"

Он может отображаться некорректно в предварительном просмотре XML для Android Studio, но работает должным образом.


3
Намек на предварительный просмотр xml мне очень помог
— ngu

Предварительный просмотр 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 Использование 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);

danx .. Но это отличный способ динамически создавать RotateAnimation для View ... я имею в виду динамически устанавливать угол d ..
— rijinrv

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

9

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

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

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

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


Мое изображение при вращении естественно становится немного выше на странице. Как я могу установить это?
— Я хочу знать,

Правильно ли центрировано ваше изображение? Если у вас неодинаковая прозрачность изображения, вращение может привести к изменению его положения при повороте
— thomaspsk

Нет человека, когда изображение вращается, оно использует ось. Представьте, что ваш телефон находится в вертикальном положении на вашей руке, а теперь поверните его в горизонтальное положение. Это больше не касается твоей руки. Так что есть пробел ... Но я решил это с помощью setPivotX ()
— я хочу знать,

5

Это моя реализация RotatableImageView . Использование очень легко: просто скопировать attrs.xml и RotatableImageView.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>

Если у вас есть проблемы с отображением изображения, попробуйте изменить код в методе RotatableImageView.onDraw () или используйте метод draw ().


1
Очень полезно. Спасибо, что поделился!
— Стефан Хот

Я получил исключение NullPointerException при использовании RotatableImageView. защищенный void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {int w = getDrawable (). getIntrinsicWidth (); ...} Кстати, я использовал его в коде (и имел заданное изображение по умолчанию), а не в XML.
— RRTW

этот imageView имеет странные проблемы при использовании в gridView. он становится невидимым, пока вы не прокрутите.
— разработчик Android


3

Кроме того, если вы хотите повернуть ImageView на 180 градусов по вертикали или горизонтали, вы можете использовать scaleYили scaleXсвойства и установить их в -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 невозможно при инициализации действия. Для этого, пожалуйста, обратитесь к этому решению ИЛИ установите размеры при нажатии кнопки, например

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

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

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

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

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

Удачи!


0

Другим возможным решением является создание собственного пользовательского представления изображений (скажем 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

просто напишите это в своем onesctivityResult

            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

Следуйте приведенному ниже ответу для непрерывного вращения изображения.

int i=0;

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

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

0

если вы хотите повернуть изображение на 180 градусов, поместите эти два значения в тег imageview: -

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

Объяснение: - scaleX = 1 и scaleY = 1 повторяют это нормальное состояние, но если мы добавим -1 в свойство scaleX / scaleY, то оно будет повернуто на 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" />
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.