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.