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. (Ви можете просто просто натиснути кнопку "Експертні властивості" праворуч, якщо вас не турбує використання макета "Текст"!)
Fattie

знайти відповідь тут. stackoverflow.com/a/52983423/5872337
Geet Тхакур

Відповіді:


194

Ще один простий спосіб повернути ImageView:
UPDATE:
Необхідний імпорт:

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значеннях:matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
Стефан Хот,

2
як обертати перегляд зображень на кожному дотику?
Саураб

14
для мене, якщо повернутись у відносному компонуванні, imageView зростає до розміру зображення, яке міститься, більше не вписуючись у макет. Хтось має досвід, як це вирішити?
Макібо

7
Примітка: для цього на роботу, ви повинні встановити ваш ImageView«S srcатрибут.getDrawable()повертав для мене null, поки я не зрозумів, що я встановив атрибут ImageView's backgroundзамість src. facepalm
Gary S.

1
Він обертає зображення лише в режимі перегляду зображень. Що мені робити для обертання самого зображення?
Еге

177

mImageView.setRotation(angle) з API> = 11


3
Чи це також змінило б ширину та висоту виду на правильний розмір? чи це змінюється лише як це виглядає?
андроїд розробник

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"

Можливо, він не відображається належним чином у попередньому перегляді Android Studio xml, але він працює як очікувалося.


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 = getDravable (). getIntrinsicWidth (); ...} BTW, я використовував його в коді (і маю задане зображення за замовчуванням), а не в xml.
RRTW

Цей imageView має дивні проблеми при використанні в gridView. він стає невидимим, поки ви не прокрутите.
андроїд розробник


3

Крім того, якщо ви хочете повернути ImageView на 180 градусів вертикально або горизонтально, ви можете використовувати scaleYабо scaleXвластивості та встановити їх на -1f. Ось приклад Котліна:

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

Це рішення достатньо для вищезазначеної проблеми. Хоча це зменшить imageView, навіть якщо це не потрібно (коли висота менша за ширину). Якщо це вас турбує, ви можете додати ще одного потрійного оператора у масштабіX / 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

На жаль, я не думаю, що існує. TheMatrixКлас відповідає за все маніпуляції зображення, будь то поворот, скорочується / росте, перекіс і т.д.

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

просто запишіть це у свій 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

Дотримуйтесь нижченаведеної відповіді для безперервного обертання зображення

int i=0;

Якщо натиснути кнопку повороту

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

0

якщо ви хочете повернути зображення на 180 градусів, то поставте ці два значення в тег перегляду зображень: -

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.