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);
rijinrv
fonte
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
encontre a resposta aqui. stackoverflow.com/a/52983423/5872337
Geet Thakur

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.

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

Frolik
fonte
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.

Oleksiy
fonte
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);
Rotemmiz
fonte
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.

thomaspsk
fonte
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 ().

petrnohejl
fonte
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
5

Também pode ser feito desta maneira: -

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

veio daqui.

Debasish Ghosh
fonte
Obrigado! É muito fácil e rápido
zinonX
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
Yamashiro Rion
fonte
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.

Gaurav Chaudhari
fonte
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);
        }
    });
Trk
fonte
2

Gire uma imagem no android com atraso:

imgSplash.animate().rotationBy(360f).setDuration(3000).setInterpolator(new LinearInterpolator()).start();
Aftab Alam
fonte
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);
    }
}

jeet.chanchawat
fonte
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

desenvolvedor android
fonte
1

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

iv.setRotation(float)
mgm
fonte
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.

Aziz
fonte
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!

roboguy12
fonte
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.

Navin Ilavarasan
fonte
0

sem matriz e animado:

{
    img_view = (ImageView) findViewById(R.id.imageView);
    rotate = new RotateAnimation(0 ,300);
    rotate.setDuration(500);
    img_view.startAnimation(rotate);
}
user4747884
fonte
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); 
Mundo do entretenimento
fonte
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);
            }
        }
Gaurav Sharma
fonte
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);
SWAPDROiD
fonte
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;
Harish Reddy
fonte
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

Prashant Kumar
fonte
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);
   }
}
Amir Hosseinzadeh
fonte
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" />
JB-
fonte