Android: ruota l'immagine in visualizzazione immagine di un angolo


154

Sto usando il seguente codice per ruotare un'immagine in ImageView di un angolo. È disponibile un metodo più semplice e meno complesso?

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 per il 2014, sembra che tu possa semplicemente impostare la "rotazione" nell'XML in Android Studio. (Puoi anche semplicemente fare clic sul pulsante "Proprietà esperte" sulla destra, se non puoi essere disturbato utilizzando il layout "Testo"!)
Fattie

trova la risposta proprio qui. stackoverflow.com/a/52983423/5872337
Geet Thakur

Risposte:


194

Un altro modo semplice per ruotare un ImageView:
AGGIORNAMENTO:
Importazioni richieste:

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

Codice: (Supponendo imageView, angle, pivotXe pivotYsono già definiti)

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

Questo metodo non richiede la creazione di una nuova bitmap ogni volta.

NOTA: Per ruotare un ImageViewsu ontouch in fase di esecuzione è possibile impostare onTouchListener su ImageViewe ruotarlo con l'aggiunta di due linee (cioè postrotate matrice e impostarlo su IMAGEVIEW ) nella sezione di codice di cui sopra nel tuo tocco ascoltatore ACTION_MOVE parte.


109
Per completezza ecco la linea basata sui ImageViewvalori di:matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
Stefan Hoth,

2
come ruotare imageview su ogni evento touch?
Saurabh,

14
per me, se ruotato in un relativo layout, imageView cresce fino alla dimensione dell'immagine contenuta, non adattandosi più al layout. Qualcuno ha esperienza su come risolvere questo?
Makibo,

7
Nota: per questo al lavoro, è necessario impostare la ImageView's srcattributo. getDrawable()stava tornando null per me fino a quando ho capito che avevo impostato la ImageView's backgroundattributi al posto di src. facepalm
Gary S.

1
Ruota l'immagine solo in imageview. Cosa devo fare per ruotare anche l'immagine stessa?
Ege,

178

mImageView.setRotation(angle) con API> = 11


3
cambierebbe anche la larghezza e l'altezza della vista alla dimensione corretta? o cambia solo come appare?
sviluppatore Android

5
C'è un modo per avere una "animazione di rotazione" durante la rotazione?
Ivan Morgillo,

13
@IvanMorgillo Puoi dare un'occhiata ViewPropertyAnimator, che viene usato comeaView.animate().rotation(20).start()
Jokester

5
@IvanMorgillo: utilizzare rotationBy(). Ad esempio view.animate().rotationBy(180f).start(),. Ma diventa problematico se si fa clic sulla vista in successione.
Mangesh,

Sto usando questo codice in un pulsante. Il primo clic è ok, ma i clic successivi non ruotano più. Dovrei mettere qualche altra riga per risolvere questo problema?
Eggakin Baconwalker,

73

Se stai supportando API 11 o successiva, puoi semplicemente utilizzare il seguente attributo XML:

android:rotation="90"

Potrebbe non essere visualizzato correttamente nell'anteprima xml di Android Studio, ma funziona come previsto.


3
Il suggerimento riguardante l'anteprima di XML mi ha aiutato molto
ngu

L'anteprima XML viene visualizzata correttamente dopo l'applicazione della rotazione.
Dick Lucas,

Questo ruoterà la vista ma non l'immagine! Ciò aggiungerà aree vuote accanto all'immagine. Aggiungi a backgroundper vedere l'effetto.
YBrush

43

Esistono due modi per farlo:

1 Utilizzo Matrixper creare una nuova 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 uso RotateAnimationsul Viewsi desidera ruotare, e assicurarsi che il set di animazione a fillAfter=true, duration=0efromDegrees=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"
/>

e gonfia l'animazione nel codice:

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

danx .. Ma è davvero un modo per fare RotateAnimation on the View in modo dinamico ... intendo impostare un angolo d in modo dinamico ..
rijinrv,

funziona meglio della risposta accettata se l'immagine che devi ruotare è in ListView
Daren

9

So che è follemente in ritardo, ma è stato utile per me, quindi potrebbe aiutare gli altri.

A partire dall'API 11, è possibile impostare la rotazione assoluta di un ImageView a livello di codice utilizzando il imageView.setRotation(angleInDegrees);metodo

In assoluto, intendo che puoi chiamare ripetutamente questa funzione senza dover tenere traccia della rotazione corrente. Significa che, se giro passando 15Fal setRotation()metodo e quindi richiamo di setRotation()nuovo con 30F, la rotazione dell'immagine sarà di 30 gradi, non di 45 gradi.

Nota: questo funziona effettivamente per qualsiasi sottoclasse dell'oggetto View , non solo per ImageView.


La mia immagine a rotazione diventa naturalmente un po 'più alta sulla pagina. Come posso impostarlo?
Voglio sapere il

L'immagine è centrata correttamente? Se hai una quantità di trasparenza irregolare nell'immagine, la rotazione può far sì che appaia cambiando posizione durante la rotazione
thomaspsk,

Nessun uomo, quando l'immagine ruota utilizza l'asse. Immagina il tuo cellulare in posizione verticale sulla tua mano, ora ruotalo in orizzontale. Non ti tocca più la mano. Quindi c'è uno spazio ... Ma l'ho risolto usando setPivotX ()
Voglio sapere il

5

Questa è la mia implementazione di RotatableImageView . L'uso è molto semplice: basta copiare attrs.xml e RotatableImageView.java nel progetto e aggiungere RotatableImageView al layout. Impostare l'angolo di rotazione desiderato usando l' esempio: parametro angolo .

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

In caso di problemi con la visualizzazione dell'immagine, provare a modificare il codice nel metodo RotatableImageView.onDraw () o utilizzare invece il metodo draw ().


1
Molto utile. Grazie per la condivisione!
Stefan Hoth,

Ho ottenuto una NullPointerException durante l'utilizzo di RotatableImageView. protetto void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {int w = getDrawable (). getIntrinsicWidth (); ...} A proposito, lo stavo usando nel codice (e avevo una data immagine predefinita), non in xml.
RRTW

questo imageView presenta strani problemi quando viene utilizzato in un gridView. continua a diventare invisibile fino allo scorrimento.
sviluppatore Android


3

Inoltre, se si desidera ruotare un ImageView di 180 gradi in verticale o in orizzontale, è possibile utilizzare scaleYo le scaleXproprietà e impostarle su -1f. Ecco un esempio di Kotlin:

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

1f valore viene utilizzato per riportare un ImageView al suo stato normale:

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

2

Ho una soluzione a questo. In realtà è una soluzione a un problema che si presenta dopo la rotazione (l'immagine rettangolare non si adatta a ImagView) ma copre anche il tuo problema .. Sebbene questa soluzione abbia l'animazione nel bene e nel male

    int h,w;
    Boolean safe=true;

Non è possibile ottenere i parametri di imageView durante l'inizializzazione dell'attività Per fare ciò, fare riferimento a questa soluzione O impostare le dimensioni su onClicca su un pulsante in questo modo

    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 
       }

E il codice da eseguire quando vogliamo ruotare 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();
        }
    });

Questa soluzione è sufficiente per il problema sopra. Anche se ridurrà l'immagine View anche se non è necessaria (quando l'altezza è inferiore alla larghezza). Se ti dà fastidio, puoi aggiungere un altro operatore ternario all'interno di scaleX / scaleY.


2

Penso che il metodo migliore :)

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

2

Ruota un'immagine in Android con ritardo:

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

1

prova questo su una vista personalizzata

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

ecco una bella soluzione per mettere un disegno ruotabile per un 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;
}

utilizzo:

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

un'altra alternativa:

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

inoltre, se desideri ruotare la bitmap, ma hai paura di OOM, puoi utilizzare una soluzione NDK che ho creato qui


1

Se vuoi solo ruotare la vista visivamente puoi usare:

iv.setRotation(float)

1

Per Kotlin,

mImageView.rotation = 90f //angle in float

Ciò ruoterà imageView anziché ruotare l'immagine

Inoltre, sebbene sia un metodo in Viewclasse. Quindi puoi praticamente ruotare qualsiasi vista utilizzandola.


0

Purtroppo, non penso che ci sia. La Matrixclasse è responsabile di tutte le manipolazioni delle immagini, che si tratti di rotazione, riduzione / crescita, inclinazione, ecc.

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

Mi scuso, ma non riesco a pensare a un'alternativa. Forse qualcun altro potrebbe essere in grado di farlo, ma le volte che ho dovuto manipolare un'immagine ho usato una matrice.

Buona fortuna!


0

Un'altra possibile soluzione è quella di creare la tua vista immagine personalizzata (diciamo RotateableImageView extends ImageView) ... e sovrascrivere onDraw () per ruotare la tela / bitmap prima di eseguire il redering sulla tela. Non dimenticare di ripristinare la tela.

Ma se hai intenzione di ruotare solo una singola istanza di visualizzazione immagine, la tua soluzione dovrebbe essere abbastanza buona.


0

senza matrice e animato:

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

0

scrivi questo nel tuo 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

Prova questo codice funzionante al 100%;

Sul pulsante di rotazione fai clic su Scrivi questo codice:

        @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

Invece di convertire l'immagine in bitmap e quindi ruotarla, prova a ruotare la visualizzazione diretta dell'immagine come sotto il codice.

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

Seguire la risposta di seguito per la rotazione continua di una visualizzazione immagine

int i=0;

Se si fa clic sul pulsante di rotazione

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

0

se vuoi ruotare un'immagine di 180 gradi, inserisci questi due valori nel tag imageview: -

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

Spiegazione: - scaleX = 1 e scaleY = 1 rappresentano lo stato normale ma se mettiamo -1 sulla proprietà scaleX / scaleY, verrà ruotato di 180 gradi


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

come usare?

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

Puoi semplicemente usare l' attributo di rotazione di ImageView

Di seguito è riportato l'attributo di ImageView con dettagli dalla fonte Android

<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.