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

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.


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


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.


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

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.


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.


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


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

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.


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

2

Rotar una imagen en Android con retraso:

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

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


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í


1

Si solo desea rotar la vista visualmente, puede usar:

iv.setRotation(float)

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.


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!


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.


0

sin matriz y animada:

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

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

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

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

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;

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


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

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" />
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.