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.