Android: girar a imagem na visualização de imagem por um ângulo


154

Estou usando o código a seguir para girar uma imagem no ImageView por um ângulo. Existe algum método mais simples e menos complexo disponível.

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 para 2014, parece que você pode simplesmente definir "rotação" no XML no Android Studio. (Você pode até clicar no botão "propriedades especializadas" à direita, se não puder se incomodar em usar o layout 'Texto'!)
— Fattie

Respostas:


194

Outra maneira simples de girar um ImageView:
UPDATE:
Importações necessárias:

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

Código: (Supondo imageView, angle, pivotXe pivotYjá estão definidos)

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

Este método não requer a criação de um novo bitmap a cada vez.

NOTA: Para rodar uma ImageViewem OnTouch em tempo de execução pode definir onTouchListener on ImageView& girá-lo adicionando duas últimas linhas (ou seja postRotate matriz e defini-lo em imageView ) na seção código acima em seu toque ouvinte ACTION_MOVE parte.


109
Para completude, aqui está a linha com base nos ImageViewvalores de:matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
— Stefan Hoth

2
como girar a visualização de imagem em cada evento de toque?
— Saurabh 23/01

14
para mim, se girado em um relativoLayout, o imageView aumenta para o tamanho da imagem contida, não cabendo mais no layout. Alguém tem experiência em como resolver isso?
— Makibo

7
Nota: Para que isso funcione, você tem que definir o seu ImageView's srcatributo. getDrawable()estava retornando nulo para mim até que percebi que havia definido o atributo ImageView's em backgroundvez de src. facepalm
— Gary S.

1
Ele gira a imagem apenas na visualização de imagens. O que devo fazer para girar a própria imagem também?
— Ege

178

mImageView.setRotation(angle) com API> = 11


3
isso também mudaria a largura e a altura da vista para o tamanho correto? ou muda apenas a aparência?
— desenvolvedor android

5
Existe uma maneira de ter uma "animação de rotação" durante a rotação?
— Ivan Morgillo

13
@IvanMorgillo Você pode dar uma olhada ViewPropertyAnimator, que é usada comoaView.animate().rotation(20).start()
— Jokester

5
@IvanMorgillo: Use rotationBy(). Por exemplo view.animate().rotationBy(180f).start(),. Mas torna-se problemático se a vista for clicada sucessivamente.
— Mangesh

Estou usando esse código em um botão. O primeiro clique está ok, mas os próximos cliques não são mais rotacionados. Devo colocar alguma outra linha para corrigir isso?
— Eggakin Baconwalker

73

Se você oferece suporte à API 11 ou superior, basta usar o seguinte atributo XML:

android:rotation="90"

Pode não ser exibido corretamente na visualização xml do Android Studio, mas funciona conforme o esperado.


3
A dica sobre a pré-visualização xml me ajudou muito
— ngu

A visualização XML é exibida corretamente para mim após a rotação ser aplicada.
— Dick Lucas

Isso girará a exibição, mas não a imagem! Isso adicionará áreas em branco ao lado da imagem. Basta adicionar a backgroundpara ver o efeito.
— YBrush 8/03/19

43

Existem duas maneiras de fazer isso:

1 Usando Matrixpara criar um novo 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 utilização RotateAnimationno Viewque deseja girar, e certifique-se o conjunto de animação para 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 Inflate the Animation no código:

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

danx .. Mas é dere maneira ny fazer RotateAnimation na média Ver dynamically..i ao conjunto d ângulo dinamicamente ..
— rijinrv

isso funciona melhor do que a resposta aceita se a imagem que você precisa para rodar está em um ListView
— Daren

9

Sei que isso é insanamente tarde, mas foi útil para mim, pois pode ajudar os outros.

A partir da API 11, você pode definir a rotação absoluta de um ImageView programaticamente usando o comando imageView.setRotation(angleInDegrees); método

Por absoluto, quero dizer que você pode chamar repetidamente essa função sem ter que acompanhar a rotação atual. Ou seja, se eu girar passando 15Fpara o setRotation()método e depois ligar setRotation()novamente com 30F, a rotação da imagem será 30 graus, não 45 graus.

Nota: Isso realmente funciona para qualquer subclasse do objeto View , não apenas para o ImageView.


Minha imagem na rotação fica naturalmente um pouco mais alta na página. Como posso definir isso?
— Eu quero saber em

Sua imagem está centralizada corretamente? Se você tiver uma quantidade irregular de transparência da sua imagem, rotação pode causar-lhe a aparecer para mudar de posição durante a rotação
— thomaspsk

Ninguém, quando a imagem gira, ela usa o eixo. Imagine o seu celular na posição vertical da sua mão, agora gire-o para a horizontal. Não toca mais na sua mão. Portanto, há um espaço ... Mas eu o resolvi usando setPivotX ()
— Eu quero saber

5

Esta é a minha implementação do RotatableImageView . O uso é muito fácil: basta copiar attrs.xml e RotatableImageView.java no seu projeto e adicionar RotatableImageView ao seu layout. Defina o ângulo de rotação desejado usando o exemplo: parâmetro 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>

Se você tiver algum problema com a exibição da imagem, tente alterar o código no método RotatableImageView.onDraw () ou use o método draw ().


1
Muito útil. Obrigado por compartilhar!
— Stefan Hoth

Eu recebi uma NullPointerException enquanto usava RotatableImageView. void protegido onMeasure (int widthMeasureSpec, int heightMeasureSpec) {int w = getDrawable (). getIntrinsicWidth (); ...} BTW, eu estava usando no código (e tenho uma determinada imagem padrão), não no xml.
— RRTW

este imageView apresenta problemas estranhos ao ser usado em um gridView. ele fica invisível até você rolar.
— desenvolvedor android


3

Além disso, se você quiser girar um ImageView em 180 graus na vertical ou na horizontal, poderá usar scaleYou scaleXproperties e defini-los como -1f. Aqui está um exemplo do Kotlin:

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

1f O valor é usado para retornar um ImageView ao seu estado normal:

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

2

Eu tenho uma solução para isso. Na verdade, é uma solução para um problema que surge após a rotação (a imagem retangular não se encaixa no ImagView), mas também cobre o seu problema. Embora essa solução tenha Animação para melhor ou para pior

    int h,w;
    Boolean safe=true;

Não é possível obter os parâmetros do imageView na inicialização da atividade. Para isso, consulte esta solução OU defina as dimensões em onClick of a Button like this

    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 o código a ser executado quando queremos rotacionar o 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 solução é suficiente para o Problema acima. Embora ela reduza o imageView, mesmo que não seja necessário (quando a altura for menor que Largura). Se isso lhe incomoda, você pode adicionar outro operador ternário em scaleX / scaleY.


2

Eu acho que o melhor método :)

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

2

Gire uma imagem no android com atraso:

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

1

tente isso em uma exibição 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

aqui está uma boa solução para colocar um drawable girado para uma imagem

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

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

Além disso, se você deseja girar o bitmap, mas com medo do OOM, pode usar uma solução NDK que criei aqui


1

Se você deseja girar a vista apenas visualmente, pode usar:

iv.setRotation(float)

1

Para Kotlin,

mImageView.rotation = 90f //angle in float

Isso girará o imageView em vez de girar a imagem

Além disso, embora seja um método em Viewclasse. Assim, você pode girar praticamente qualquer visualização usando-a.


0

Infelizmente, acho que não existe. oMatrix classe é responsável por todas as manipulações de imagem, seja girando, diminuindo / aumentando, enviesando etc.

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

Peço desculpas, mas não consigo pensar em uma alternativa. Talvez outra pessoa possa, mas nas vezes em que tive que manipular uma imagem usei uma Matrix.

Boa sorte!


0

Outra solução possível é criar sua própria exibição de imagem personalizada (por exemplo RotateableImageView extends ImageView) ... e substituir o onDraw () para girar a tela / bitmaps antes de voltar para a tela. Não se esqueça de restaurar a tela novamente.

Mas se você for rotacionar apenas uma única instância da visualização de imagem, sua solução deve ser boa o suficiente.


0

sem matriz e animado:

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

0

basta escrever isso em seu 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

Experimente este código 100% funcionando;

No botão girar, clique em escrever 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

Em vez de converter a imagem em bitmap e girá-la, tente girar a exibição direta da imagem, como abaixo do código.

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 a resposta abaixo para rotação contínua de uma visualização de imagem

int i=0;

Se clicar no botão girar

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

0

se você quiser girar uma imagem em 180 graus, coloque esses dois valores na tag imageview: -

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

Explicação: - scaleX = 1 e scaleY = 1 representam seu estado normal, mas se colocarmos -1 na propriedade scaleX / scaleY, ele será girado 180 graus


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

Como usar?

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

Você pode simplesmente usar rotação atributo de do ImageView

Abaixo está o atributo do ImageView com detalhes da fonte do Android

<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.