Android: gire la imagen en la vista de imagen por un ángulo

154

Estoy usando el siguiente código para rotar una imagen en ImageView por un ángulo. ¿Existe algún método más simple y menos complejo disponible?

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);
rijinrv
fuente
66
PD para 2014, parece que simplemente puede configurar la "rotación" en el XML en Android Studio. (¡Incluso puede hacer clic en el botón "propiedades expertas" a la derecha, si no puede molestarse con el diseño 'Texto'!)
Fattie
encuentra la respuesta aquí mismo. stackoverflow.com/a/52983423/5872337
Geet Thakur el

Respuestas:

194

Otra forma simple de rotar un ImageView:
ACTUALIZACIÓN:
Importaciones requeridas:

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

Código: (Asumiendo imageView, angle, pivotXy pivotYya están definidos)

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

Este método no requiere crear un nuevo mapa de bits cada vez.

NOTA: Para girar una ImageViewen ontouch en tiempo de ejecución se puede establecer onTouchListener en ImageViewy girarlo mediante la adición de las últimas dos líneas (es decir postrotate matriz y la pusieron en imageView ) en la sección de código anterior en su toque oyente ACTION_MOVE parte.

Aks
fuente
109
Para completar, aquí está la línea basada en los ImageViewvalores de 's:matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
Stefan Hoth
2
¿Cómo rotar la vista de imagen en cada evento táctil?
Saurabh
14
para mí, si gira en un diseño relativo, el imageView crece al tamaño de la imagen contenida, ya no se ajusta al diseño. ¿Alguien tiene experiencia en cómo resolver esto?
Makibo el
77
Nota: para que esto funcione, usted tiene que configurar su ImageView's srcatributo. getDrawable()estaba volviendo nulo para mí hasta que me di cuenta de que había establecido el atributo ImageView's en backgroundlugar de src. facepalm
Gary S.
1
Rota la imagen solo en vista de imagen. ¿Qué debo hacer para rotar la imagen también?
Ege
178

mImageView.setRotation(angle) con API> = 11

Frolik
fuente
3
¿también cambiaría el ancho y la altura de la vista al tamaño correcto? o cambia solo como se ve?
Desarrollador de Android
55
¿Hay alguna manera de tener una "animación de rotación" mientras se rota?
Ivan Morgillo
13
@IvanMorgillo Puedes echar un vistazo ViewPropertyAnimator, que se usa comoaView.animate().rotation(20).start()
Jokester
55
@IvanMorgillo: Uso rotationBy(). Por ejemplo, view.animate().rotationBy(180f).start(). Pero se vuelve problemático si se hace clic sucesivamente en la vista.
Mangesh
Estoy usando este código en un botón. El primer clic está bien, pero los siguientes clics ya no giran. ¿Debo poner alguna otra línea para arreglar esto?
Eggakin Baconwalker
73

Si admite API 11 o superior, puede usar el siguiente atributo XML:

android:rotation="90"

Es posible que no se muestre correctamente en la vista previa xml de Android Studio, pero funciona como se esperaba.

Oleksiy
fuente
3
La sugerencia sobre la vista previa xml me ayudó mucho
ngu
La vista previa de XML se muestra correctamente después de aplicar la rotación.
Dick Lucas
¡Esto rotará la vista pero no la imagen! Esto agregará áreas en blanco al lado de la imagen. Simplemente agregue un backgroundpara ver el efecto.
YBrush
43

Hay dos maneras de hacerlo:

1 Utilizando Matrixpara crear un nuevo mapa de bits:

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 RotateAnimationen el Viewque desea girar, y asegúrese de que el conjunto de Animación a fillAfter=true, duration=0yfromDegrees=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 inflar la animación en código:

Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotation);
myView.startAnimation(rotation);
Rotemmiz
fuente
DanX .. Pero es dere manera ny hacer RotateAnimation en la media Ver dynamically..i para ajustar el ángulo d dinámicamente ..
rijinrv
esto funciona mejor que la respuesta aceptada si la imagen que necesita rotar está en ListView
Daren
9

Sé que esto es increíblemente tarde, pero fue útil para mí, por lo que puede ayudar a otros.

A partir de API 11, puede establecer la rotación absoluta de un ImageView mediante programación utilizando imageView.setRotation(angleInDegrees); método

Por absoluto, quiero decir que puede llamar repetidamente a esta función sin tener que realizar un seguimiento de la rotación actual. Es decir, si giro pasando 15Fal setRotation()método y luego setRotation()vuelvo a llamar con 30F, la rotación de la imagen será de 30 grados, no de 45 grados.

Nota: Esto realmente funciona para cualquier subclase del objeto View , no solo ImageView.

Thomaspsk
fuente
Mi imagen en rotación se vuelve naturalmente un poco más alta en la página. ¿Cómo puedo dejarlo?
Quiero saber
¿Tu imagen está centrada correctamente? Si tiene una cantidad desigual de transparencia en su imagen, la rotación puede hacer que parezca cambiar de posición al girar
thomaspsk
Ningún hombre, cuando la imagen gira, usa el eje. Imagine su teléfono celular en posición vertical en su mano, ahora gírelo a horizontal. Ya no toca tu mano. Entonces hay un espacio ... Pero lo resolví usando setPivotX ()
Quiero saber
5

Esta es mi implementación de RotatableImageView . Su uso es muy fácil: sólo tienes que copiar attrs.xml y RotatableImageView.java en su proyecto y añadir RotatableImageView a su disposición. Establezca el ángulo de rotación deseado con el ejemplo: parámetro de ángulo .

<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 tiene algunos problemas para mostrar la imagen, intente cambiar el código en el método RotatableImageView.onDraw () o use el método draw () en su lugar.

petrnohejl
fuente
1
Muy útil. ¡Gracias por compartir!
Stefan Hoth
Obtuve una NullPointerException mientras usaba RotatableImageView. vacío protegido onMeasure (int widthMeasureSpec, int heightMeasureSpec) {int w = getDrawable (). getIntrinsicWidth (); ...} Por cierto, lo estaba usando en código (y tengo una imagen predeterminada dada), no en xml.
RRTW
Este imageView tiene problemas extraños cuando se usa en un gridView. se vuelve invisible hasta que te desplazas.
Desarrollador de Android
5

También se puede hacer de esta manera: -

imageView.animate().rotation(180).start();

Tengo de aquí.

Debasish Ghosh
fuente
¡Gracias! Es muy fácil y rápido
zinonX
3

Además, si desea rotar un ImageView 180 grados vertical u horizontalmente, puede usar scaleYo scaleXpropiedades y establecerlas en -1f. Aquí hay un ejemplo de Kotlin:

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

1f El valor se utiliza para devolver un ImageView a su estado normal:

imageView.scaleY = 1f
imageView.scaleX = 1f
Yamashiro Rion
fuente
2

Tengo una solución para esto. En realidad, es una solución a un problema que surge después de la rotación (la imagen rectangular no se ajusta a ImagView) pero también cubre su problema. Aunque esta solución tiene animación para bien o para mal

    int h,w;
    Boolean safe=true;

No es posible obtener los parámetros de imageView al iniciar la actividad. Para hacerlo, consulte esta solución O configure las dimensiones en onHaga clic en un botón como este

    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 
       }

Y el código que se ejecutará cuando queramos rotar 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();
        }
    });

Esta solución es suficiente para el problema anterior. Aunque reducirá la vista de imagen incluso si no es necesario (cuando la altura es menor que el ancho). Si le molesta, puede agregar otro operador ternario dentro de scaleX / scaleY.

Gaurav Chaudhari
fuente
2

Creo que el mejor método :)

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

Rotar una imagen en Android con retraso:

imgSplash.animate().rotationBy(360f).setDuration(3000).setInterpolator(new LinearInterpolator()).start();
Aftab Alam
fuente
1

prueba esto en una vista personalizada

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

jeet.chanchawat
fuente
1

Aquí hay una buena solución para poner un dibujo giratorio para una 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;
}

uso:

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

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

Además, si desea rotar el mapa de bits, pero tiene miedo de OOM, puede usar una solución NDK que he creado aquí

desarrollador de Android
fuente
1

Si solo desea rotar la vista visualmente, puede usar:

iv.setRotation(float)
mgm
fuente
1

Para Kotlin

mImageView.rotation = 90f //angle in float

Esto rotará la imagen Vista en lugar de girar la imagen

Además, aunque es un método en Viewclase. Por lo tanto, puede rotar prácticamente cualquier vista usándolo.

Aziz
fuente
0

Lamentablemente, no creo que haya. La Matrixclase es responsable de todas las manipulaciones de imágenes, ya sea rotando, encogiendo / creciendo, sesgando, etc.

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

Mis disculpas, pero no puedo pensar en una alternativa. Tal vez alguien más pueda hacerlo, pero las veces que he tenido que manipular una imagen he usado una matriz.

¡La mejor de las suertes!

roboguy12
fuente
0

Otra posible solución es crear su propia vista de imagen personalizada (digamos RotateableImageView extends ImageView ) ... y anular onDraw () para rotar los lienzos / mapas de bits antes de volver al lienzo. No olvide restaurar el lienzo nuevamente.

Pero si va a rotar solo una instancia de vista de imagen, su solución debería ser lo suficientemente buena.

Navin Ilavarasan
fuente
0

sin matriz y animada:

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

solo escribe esto en tu 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); 
Mundo del entretenimiento
fuente
0

Pruebe este código 100% de trabajo;

Al hacer clic en el botón rotar, escriba este código:

        @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);
            }
        }
Gaurav Sharma
fuente
0

En lugar de convertir la imagen en mapa de bits y luego girarla, intente girar la vista de imagen directa como se muestra a continuación.

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);
SWAPDROID
fuente
0

Siga la respuesta a continuación para la rotación continua de una vista de imagen

int i=0;

Si se hace clic en el botón rotar

imageView.setRotation(i+90);
i=i+90;
Harish Reddy
fuente
0

si desea rotar una imagen 180 grados, coloque estos dos valores en la etiqueta imageview: -

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

Explicación: - scaleX = 1 y scaleY = 1 se repiten, es estado normal, pero si ponemos -1 en la propiedad scaleX / scaleY, se rotará 180 grados

Prashant Kumar
fuente
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);

¿cómo utilizar?

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);
   }
}
Amir Hosseinzadeh
fuente
0

Simplemente puede usar el atributo de rotación de ImageView

A continuación se muestra el atributo de ImageView con detalles de la fuente de Android

<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />
JB-
fuente