Android: Bild in der Bildansicht um einen Winkel drehen


154

Ich verwende den folgenden Code, um ein Bild in ImageView um einen Winkel zu drehen. Gibt es eine einfachere und weniger komplexe Methode?

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 für 2014, es sieht so aus, als könnten Sie in XML in Android Studio einfach "Rotation" einstellen. (Sie können sogar einfach auf die Schaltfläche "Experteneigenschaften" rechts klicken, wenn Sie sich nicht um das Layout "Text" kümmern müssen!)
Fattie

Hier finden Sie eine Antwort. stackoverflow.com/a/52983423/5872337
Geet Thakur

Antworten:


194

Eine weitere einfache Möglichkeit zum Drehen von ImageView:
UPDATE:
Erforderliche Importe:

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

Code: (Unter der Annahme imageView, angle, pivotX& pivotYist bereits definiert)

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

Bei dieser Methode muss nicht jedes Mal eine neue Bitmap erstellt werden.

HINWEIS: Zum Drehen eines ImageViewauf OnTouch zur Laufzeit können Sie einstellen onTouchListener auf ImageView& drehen sie durch Zugabe letzte beiden Zeilen (dh postrotate Matrix & stellt es auf Imageview ) in über Code - Abschnitt in Ihrem Touch - Hörer ACTION_MOVE Teil.


109
Der Vollständigkeit halber ist hier die Zeile basierend auf den ImageViewWerten von:matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
Stefan Hoth

2
Wie kann ich die Bildansicht bei jedem Berührungsereignis drehen?
Saurabh

14
Wenn ich in einem relativen Layout gedreht werde, wächst die Bildansicht auf die Größe des enthaltenen Bilds und passt nicht mehr in das Layout. Hat jemand Erfahrung, wie man das löst?
Makibo

7
Hinweis: Damit dies funktioniert, müssen Sie ImageViewdas srcAttribut Ihres 's festlegen . getDrawable()gab für mich null zurück, bis mir klar wurde, dass ich stattdessen das Attribut ImageView' gesetzt hatte . Gesichtspalmebackgroundsrc
Gary S.

1
Das Bild wird nur in der Bildansicht gedreht. Was soll ich tun, um das Bild selbst zu drehen?
Ege

177

mImageView.setRotation(angle) mit API> = 11


3
Würde es auch die Breite und Höhe der Ansicht auf die richtige Größe ändern? oder ändert es nur, wie es aussieht?
Android-Entwickler

5
Gibt es eine Möglichkeit, beim Drehen eine "Rotationsanimation" zu erstellen?
Ivan Morgillo

13
@ IvanMorgillo Sie können einen Blick auf werfen ViewPropertyAnimator, die verwendet wird wieaView.animate().rotation(20).start()
Jokester

5
@ IvanMorgillo: Verwenden rotationBy(). Zum Beispiel view.animate().rotationBy(180f).start(). Es wird jedoch problematisch, wenn die Ansicht nacheinander angeklickt wird.
Mangesh

Ich verwende diesen Code in einer Schaltfläche. Der erste Klick ist in Ordnung, aber die nächsten Klicks drehen sich nicht mehr. Sollte ich eine andere Zeile einfügen, um dies zu beheben?
Eggakin Baconwalker

73

Wenn Sie API 11 oder höher unterstützen, können Sie einfach das folgende XML-Attribut verwenden:

android:rotation="90"

In der XML-Vorschau von Android Studio wird es möglicherweise nicht richtig angezeigt, aber es funktioniert wie erwartet.


3
Der Hinweis bezüglich der XML-Vorschau hat mir sehr geholfen
ngu

Die XML-Vorschau wird für mich ordnungsgemäß angezeigt, nachdem die Drehung angewendet wurde.
Dick Lucas

Dadurch wird die Ansicht gedreht, aber nicht das Bild! Dadurch werden leere Bereiche neben dem Bild hinzugefügt. Fügen Sie einfach ein hinzu background, um den Effekt zu sehen.
YBrush

43

Dafür gibt es zwei Möglichkeiten:

1 MatrixErstellen einer neuen Bitmap:

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 Verwendung RotateAnimationauf die ViewSie drehen möchten, und stellen Sie sicher , dass das Animationssatz fillAfter=true, duration=0undfromDegrees=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"
/>

und Aufblasen der Animation im Code:

Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotation);
myView.startAnimation(rotation);

danx .. Aber es ist eine gute Möglichkeit, RotateAnimation in der Ansicht dynamisch auszuführen. Ich meine, den Winkel dynamisch
einzustellen

Dies funktioniert besser als die akzeptierte Antwort, wenn sich das Bild, das Sie drehen müssen, in einer ListView befindet
Daren

9

Ich weiß, dass dies wahnsinnig spät ist, aber es war hilfreich für mich, damit es anderen helfen kann.

Ab API 11 können Sie die absolute Drehung einer ImageView programmgesteuert mithilfe von festlegen imageView.setRotation(angleInDegrees); Methode .

Mit absolut meine ich, dass Sie diese Funktion wiederholt aufrufen können, ohne die aktuelle Drehung verfolgen zu müssen. Das heißt, wenn ich durch Übergabe 15Fan die setRotation()Methode drehe und dann setRotation()erneut mit aufrufe 30F, beträgt die Drehung des Bildes 30 Grad und nicht 45 Grad.

Hinweis: Dies funktioniert tatsächlich für jede Unterklasse des View- Objekts, nicht nur für ImageView.


Mein Bild beim Drehen wird auf der Seite natürlich etwas höher. Wie kann ich es ablegen?
Ich will wissen,

Ist Ihr Bild richtig zentriert? Wenn Sie ein ungleichmäßiges Maß an Transparenz in Ihrem Bild haben, kann die Drehung dazu führen, dass sich die Position beim Drehen
ändert

Kein Mann, wenn sich das Bild dreht, benutzt es die Achse. Stellen Sie sich Ihr Mobiltelefon in vertikaler Position auf Ihrer Hand vor und drehen Sie es jetzt in die horizontale Position. Es berührt deine Hand nicht mehr. Es gibt also ein Leerzeichen ... Aber ich habe es mit setPivotX () gelöst
ich möchte es

5

Das ist mein Implementierung von RotatableImageView . Die Benutzung ist sehr einfach: einfach kopieren attrs.xml und RotatableImageView.java in Ihr Projekt und fügen Sie RotatableImageView zum Layout. Stellen Sie den gewünschten Drehwinkel anhand des Beispiels ein: Winkelparameter .

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

Wenn Sie Probleme beim Anzeigen von Bildern haben, ändern Sie den Code in der RotatableImageView.onDraw () -Methode oder verwenden Sie stattdessen die draw () -Methode.


1
Sehr hilfreich. Danke für das Teilen!
Stefan Hoth

Ich habe eine NullPointerException erhalten, als ich RotatableImageView verwendet habe. protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {int w = getDrawable (). getIntrinsicWidth (); ...} Übrigens, ich habe es im Code verwendet (und habe ein bestimmtes Standardbild), nicht in XML.
RRTW

Diese imageView hat seltsame Probleme, wenn sie in einer gridView verwendet wird. es wird unsichtbar, bis Sie scrollen.
Android-Entwickler


3

Auch, wenn Sie eine Image durch drehen möchten 180 Grad vertikal oder horizontal, können Sie verwenden scaleYoder scaleXEigenschaften und setzen Sie sie auf -1f. Hier ist ein Kotlin-Beispiel:

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

1f value wird verwendet, um eine ImageView in ihren normalen Zustand zurückzusetzen:

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

2

Ich habe eine Lösung dafür. Eigentlich ist es eine Lösung für ein Problem, das nach der Drehung auftritt (rechteckiges Bild passt nicht zu ImagView), aber es deckt auch Ihr Problem ab. Obwohl diese Lösung Animation zum Guten oder zum Schlechten hat

    int h,w;
    Boolean safe=true;

Das Abrufen der Parameter von imageView ist bei der Initialisierung der Aktivität nicht möglich. Beziehen Sie sich dazu bitte auf diese Lösung ODER stellen Sie die Abmessungen auf onClick eines Buttons wie folgt ein

    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 
       }

Und der Code, der ausgeführt werden soll, wenn ImageView gedreht werden soll

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

Diese Lösung ist für das obige Problem ausreichend. Obwohl die Bildansicht auch dann verkleinert wird, wenn dies nicht erforderlich ist (wenn die Höhe kleiner als die Breite ist). Wenn Sie dies stört, können Sie innerhalb von scaleX / scaleY einen weiteren ternären Operator hinzufügen.


2

Ich denke die beste Methode :)

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

2

Drehen Sie ein Bild in Android mit Verzögerung:

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

1

Versuchen Sie dies in einer benutzerdefinierten Ansicht

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

Hier ist eine gute Lösung, um ein gedrehtes Zeichen für eine Bildansicht zu erstellen:

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

Verwendung:

Bitmap b=...
float angle=...
final Drawable rotatedDrawable = getRotateDrawable(b,angle);
root.setImageDrawable(rotatedDrawable);

eine andere Alternative:

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

Wenn Sie die Bitmap drehen möchten, aber Angst vor OOM haben, können Sie auch eine NDK-Lösung verwenden, die ich hier erstellt habe


1

Wenn Sie die Ansicht nur visuell drehen möchten, können Sie Folgendes verwenden:

iv.setRotation(float)

1

Für Kotlin

mImageView.rotation = 90f //angle in float

Dadurch wird die Bildansicht gedreht, anstatt das Bild zu drehen

Auch wenn es eine Methode in der ViewKlasse ist. Sie können also so ziemlich jede Ansicht damit drehen.


0

Leider glaube ich nicht, dass es das gibt. Die MatrixKlasse ist für alle Bildmanipulationen verantwortlich, unabhängig davon, ob sie sich drehen, schrumpfen / wachsen, schief laufen usw.

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

Ich entschuldige mich, aber ich kann mir keine Alternative vorstellen. Vielleicht kann es jemand anderes, aber als ich ein Bild manipulieren musste, habe ich eine Matrix verwendet.

Viel Glück!


0

Eine andere mögliche Lösung besteht darin, eine eigene benutzerdefinierte Bildansicht zu erstellen (z RotateableImageView extends ImageView Bildansicht ) ... und onDraw () zu überschreiben, um entweder die Zeichenfläche oder die Bitmaps zu drehen, bevor Sie erneut auf die Zeichenfläche zugreifen. Vergessen Sie nicht, die Zeichenfläche wieder herzustellen.

Wenn Sie jedoch nur eine einzelne Instanz der Bildansicht drehen möchten, sollte Ihre Lösung gut genug sein.


0

ohne Matrix und animiert:

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

0

Schreiben Sie dies einfach in Ihr 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

Versuchen Sie, diesen Code zu 100% zu verwenden.

Klicken Sie beim Drehen auf den folgenden Code:

        @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

Anstatt das Bild in eine Bitmap zu konvertieren und es dann zu drehen, versuchen Sie, die direkte Bildansicht wie im folgenden Code zu drehen.

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

Befolgen Sie die nachstehende Antwort, um eine Bildansicht kontinuierlich zu drehen

int i=0;

Wenn Sie auf die Schaltfläche "Drehen" klicken

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

0

Wenn Sie ein Bild um 180 Grad drehen möchten, geben Sie diese beiden Werte in das Bildansichts-Tag ein: -

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

Erläuterung: - scaleX = 1 und scaleY = 1 stellen den normalen Zustand dar. Wenn wir jedoch -1 auf die Eigenschaft scaleX / scaleY setzen, wird sie um 180 Grad gedreht


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

wie benutzt man?

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

Sie können einfach das Rotationsatribute von ImageView verwenden

Unten finden Sie das Attribut von ImageView mit Details aus der Android-Quelle

<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.