Android: faire pivoter l'image dans l'image vue d'un angle


154

J'utilise le code suivant pour faire pivoter une image dans ImageView d'un angle. Existe-t-il une méthode plus simple et moins complexe?

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 pour 2014, il semble que vous puissiez simplement définir la "rotation" dans le XML dans Android Studio. (Vous pouvez même simplement cliquer sur le bouton "Propriétés expertes" sur la droite, si vous ne pouvez pas être dérangé par la mise en page "Texte"!)
Fattie

Réponses:


194

Un autre moyen simple de faire pivoter un ImageView:
MISE À JOUR:
Importations requises:

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

Code: ( En supposant imageView, angle, pivotXet pivotYsont déjà définis)

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

Cette méthode ne nécessite pas la création d'un nouveau bitmap à chaque fois.

REMARQUE: Pour faire pivoter un ImageViewsur OnTouch lors de l' exécution , vous pouvez définir onTouchListener sur ImageViewet faites -le pivoter en ajoutant deux dernières lignes (c. -à- postrotate matrice et placez - le sur imageView ) dans la section code ci - dessus dans votre écouteur toucher ACTION_MOVE partie.


109
Pour être complet, voici la ligne basée sur les ImageViewvaleurs de:matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
Stefan Hoth

2
comment faire pivoter imageview à chaque événement tactile?
Saurabh

14
pour moi, s'il est tourné dans un relativeLayout, l'imageView augmente à la taille de l'image contenue, ne rentrant plus dans la mise en page. Quelqu'un a-t-il de l'expérience pour résoudre ce problème?
Makibo

7
Remarque: pour que cela fonctionne, vous devez définir ImageViewl' srcattribut de votre. getDrawable()renvoyait null pour moi jusqu'à ce que je réalise que j'avais défini l' attribut ImageView's backgroundau lieu de src. facepalm
Gary S.

1
Il fait pivoter l'image uniquement dans la vue image. Que dois-je faire pour faire pivoter l'image elle-même?
Ege

178

mImageView.setRotation(angle) avec API> = 11


3
changerait-il également la largeur et la hauteur de la vue à la bonne taille? ou cela change-t-il seulement son apparence?
développeur android

5
Existe-t-il un moyen d'avoir une "animation de rotation" pendant la rotation?
Ivan Morgillo

13
@IvanMorgillo Vous pouvez jeter un oeil à ViewPropertyAnimator, qui est utilisé commeaView.animate().rotation(20).start()
Jokester

5
@IvanMorgillo: Utilisez rotationBy(). Par exemple view.animate().rotationBy(180f).start(),. Mais cela devient problématique si la vue est cliquée successivement.
Mangesh

J'utilise ce code dans un bouton. Le premier clic est ok, mais les clics suivants ne tournent plus. Dois-je mettre une autre ligne pour résoudre ce problème?
Eggakin Baconwalker

73

Si vous prenez en charge l'API 11 ou une version ultérieure, vous pouvez simplement utiliser l'attribut XML suivant:

android:rotation="90"

Il peut ne pas s'afficher correctement dans l'aperçu XML d'Android Studio, mais cela fonctionne comme prévu.


3
L'indice concernant l'aperçu xml m'a beaucoup aidé
ngu

L'aperçu XML s'affiche correctement pour moi une fois la rotation appliquée.
Dick Lucas

Cela fera pivoter la vue mais pas l'image! Cela ajoutera des zones vides à côté de l'image. Ajoutez simplement un backgroundpour voir l'effet.
YBrush

43

Il existe deux façons de procéder:

1 Utilisation Matrixpour créer un nouveau 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 utilisation RotateAnimationsur la Viewfaire pivoter, et assurez - vous que le jeu d'animation à fillAfter=true, duration=0etfromDegrees=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"
/>

et gonflez l'animation dans le code:

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

DanX .. Mais est sur la moyenne Voir dynamically..i pour définir l' angle d Dere ny façon de faire RotateAnimation dynamiquement ..
rijinrv

cela fonctionne mieux que la réponse acceptée si l'image que vous devez faire pivoter est dans une ListView
Daren

9

Je sais que c'est incroyablement tard, mais cela m'a été utile pour que cela puisse aider les autres.

À partir de l'API 11, vous pouvez définir la rotation absolue d'un ImageView par programme à l'aide de la imageView.setRotation(angleInDegrees);méthode.

Par absolu, je veux dire que vous pouvez appeler cette fonction à plusieurs reprises sans avoir à suivre la rotation actuelle. Cela signifie que si je fais pivoter en passant 15Fà la setRotation()méthode, puis que j'appelle à setRotation()nouveau avec 30F, la rotation de l'image doit être de 30 degrés et non de 45 degrés.

Remarque: cela fonctionne pour n'importe quelle sous-classe de l' objet View , pas seulement ImageView.


Mon image à la rotation devient naturellement un peu plus haute sur la page. Comment puis-je le déposer?
Je veux savoir

Votre image est-elle correctement centrée? Si vous avez une quantité inégale de transparence dans votre image, la rotation peut la faire changer de position lors de la rotation
thomaspsk

Personne, quand l'image tourne, elle utilise l'axe. Imaginez votre téléphone portable en position verticale sur votre main, maintenant faites-le pivoter à l'horizontale. Il ne touche plus votre main. Il y a donc un espace ... Mais je l'ai résolu en utilisant setPivotX ()
I Wanna Know

5

C'est mon implémentation de RotatableImageView . L' utilisation est très simple: il suffit de copier attrs.xml et RotatableImageView.java dans votre projet et ajouter RotatableImageView à votre disposition. Définissez l'angle de rotation souhaité à l'aide de l' exemple: paramètre d' angle .

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

Si vous rencontrez des problèmes d'affichage de l'image, essayez de modifier le code dans la méthode RotatableImageView.onDraw () ou utilisez la méthode draw () à la place.


1
Très utile. Merci d'avoir partagé!
Stefan Hoth

J'ai eu une NullPointerException en utilisant RotatableImageView. protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {int w = getDrawable (). getIntrinsicWidth (); ...} BTW, je l'ai utilisé dans le code (et j'ai une image par défaut donnée), pas en xml.
RRTW

cette imageView a des problèmes étranges lorsqu'elle est utilisée dans une gridView. il devient invisible jusqu'à ce que vous faites défiler.
développeur android


3

De plus, si vous souhaitez faire pivoter un ImageView de 180 degrés verticalement ou horizontalement, vous pouvez utiliser les propriétés scaleYou scaleXet les définir sur -1f. Voici un exemple Kotlin:

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

1f value est utilisée pour ramener une ImageView à son état normal:

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

2

J'ai une solution à cela. En fait, c'est une solution à un problème qui survient après la rotation (l'image rectangulaire ne convient pas à ImagView) mais elle couvre également votre problème. Bien que cette solution ait une animation pour le meilleur ou pour le pire

    int h,w;
    Boolean safe=true;

Obtenir les paramètres d'imageView n'est pas possible lors de l'initialisation de l'activité Pour ce faire, veuillez vous référer à cette solution OU définir les dimensions en un clic sur un bouton Comme ceci

    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 
       }

Et le code à exécuter lorsque nous voulons faire pivoter 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();
        }
    });

Cette solution est suffisante pour le problème ci-dessus, bien que cela réduise l'imageView même si ce n'est pas nécessaire (lorsque la hauteur est inférieure à la largeur) .Si cela vous dérange, vous pouvez ajouter un autre opérateur ternaire dans scaleX / scaleY.


2

Je pense que la meilleure méthode :)

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

2

Faites pivoter une image dans Android avec un délai:

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

1

essayez ceci sur une vue personnalisée

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

voici une belle solution pour mettre un dessin pivoté pour une 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;
}

usage:

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

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

aussi, si vous souhaitez faire pivoter le bitmap, mais que vous avez peur du MOO, vous pouvez utiliser une solution NDK que j'ai créée ici


1

Si vous souhaitez uniquement faire pivoter la vue visuellement, vous pouvez utiliser:

iv.setRotation(float)

1

Pour Kotlin,

mImageView.rotation = 90f //angle in float

Cela fera pivoter l'imageView plutôt que de faire pivoter l'image

Aussi, bien que ce soit une méthode en Viewclasse. Vous pouvez donc pratiquement faire pivoter n'importe quelle vue en l'utilisant.


0

Malheureusement, je ne pense pas qu'il y en ait. La Matrixclasse est responsable de toutes les manipulations d'image, qu'il s'agisse de rotation, de rétrécissement / de croissance, d'inclinaison, etc.

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

Mes excuses, mais je ne peux pas penser à une alternative. Peut-être que quelqu'un d'autre pourrait le faire, mais les fois où j'ai eu à manipuler une image, j'ai utilisé une matrice.

Bonne chance!


0

Une autre solution possible est de créer votre propre vue Image personnalisée (par exemple RotateableImageView extends ImageView) ... et de remplacer onDraw () pour faire pivoter le canevas / les bitmaps avant de les redéfinir sur le canevas. N'oubliez pas de restaurer le canevas.

Mais si vous prévoyez de ne faire pivoter qu'une seule instance de vue d'image, votre solution devrait être suffisante.


0

sans matrice et animé:

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

0

écrivez simplement ceci dans votre 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

Essayez ce code 100% fonctionnel;

Sur le bouton de rotation, cliquez sur écrire ce 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

Plutôt que de convertir l'image en bitmap, puis de la faire pivoter, essayez de faire pivoter la vue directe de l'image comme le code ci-dessous.

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

Suivez la réponse ci-dessous pour une rotation continue d'une vue d'image

int i=0;

Si le bouton de rotation est cliqué

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

0

si vous voulez faire pivoter une image de 180 degrés, mettez ces deux valeurs dans la balise imageview: -

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

Explication: - scaleX = 1 et scaleY = 1 représentent son état normal mais si nous mettons -1 sur la propriété scaleX / scaleY, il sera alors pivoté de 180 degrés


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

comment utiliser?

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

Vous pouvez simplement utiliser l' attribut de rotation d' ImageView

Voici l'attribut d'ImageView avec les détails de la source Android

<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.