Android: Obróć obraz w widoku obrazu o kąt


154

Używam następującego kodu, aby obrócić obraz w ImageView o kąt. Czy jest dostępna prostsza i mniej złożona metoda.

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 na rok 2014, wygląda na to, że możesz po prostu ustawić „obrót” w kodzie XML w Android Studio. (Możesz nawet kliknąć przycisk „Właściwości eksperta” po prawej stronie, jeśli nie przeszkadza Ci korzystanie z układu „Tekst”!)
Fattie

Odpowiedzi:


194

Kolejny prosty sposób na obrócenie ImageView:
AKTUALIZACJA:
wymagany import:

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

Kod: (Zakładając imageView, angle, pivotXi pivotYsą już zdefiniowane)

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

Ta metoda nie wymaga każdorazowego tworzenia nowej mapy bitowej.

UWAGA: Aby obrócić ImageViewna ontouch przy starcie można ustawić onTouchListener na ImageViewi obróć go dodając dwie ostatnie linie (tj postRotate matryca i ustawić go na ImageView ) w powyższej sekcji kodu w dotyku słuchacz ACTION_MOVE części.


109
Dla kompletności tutaj jest linia oparta na ImageViewwartościach:matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
Stefan Hoth

2
jak obracać widok obrazu na każdym zdarzeniu dotykowym?
Saurabh

14
dla mnie, jeśli zostanie obrócony w RelativeLayout, imageView rozrośnie się do rozmiaru zawartego obrazu, nie pasując już do układu. Czy ktoś ma doświadczenie, jak to rozwiązać?
Makibo

7
Uwaga: Aby to zadziałało, musisz ustawić swój ImageView„s srcatrybut. getDrawable()zwracał dla mnie wartość null, dopóki nie zdałem sobie sprawy, że ustawiłem atrybut ImageView's backgroundzamiast src. facepalm
Gary S.

1
Obraca obraz tylko w widoku obrazu. Co powinienem zrobić, aby obrócić sam obraz?
Ege

177

mImageView.setRotation(angle) z API> = 11


3
czy zmieniłoby to również szerokość i wysokość widoku do odpowiedniego rozmiaru? czy zmienia tylko to, jak wygląda?
programista Androida

5
Czy istnieje sposób na uzyskanie „animacji obrotu” podczas obracania?
Ivan Morgillo

13
@IvanMorgillo Możesz rzucić okiem ViewPropertyAnimator, który jest używany w następujący sposóbaView.animate().rotation(20).start()
Jokester.

5
@IvanMorgillo: Użyj rotationBy(). Na przykład view.animate().rotationBy(180f).start(). Ale staje się problematyczne, jeśli widok jest klikany sukcesywnie.
Mangesh

Używam tego kodu w przycisku. Pierwsze kliknięcie jest w porządku, ale kolejne kliknięcia już się nie obracają. Czy powinienem umieścić inną linię, aby to naprawić?
Eggakin Baconwalker,

73

Jeśli obsługujesz API 11 lub nowszy, możesz po prostu użyć następującego atrybutu XML:

android:rotation="90"

Może nie wyświetlać się poprawnie w podglądzie XML Android Studio, ale działa zgodnie z oczekiwaniami.


3
Wskazówka dotycząca podglądu XML bardzo mi pomogła
ngu

Podgląd XML wyświetla się prawidłowo po zastosowaniu rotacji.
Dick Lucas

Spowoduje to obrócenie widoku, ale nie obrazu! Spowoduje to dodanie pustych obszarów obok obrazu. Po prostu dodaj, backgroundaby zobaczyć efekt.
YBrush

43

Można to zrobić na dwa sposoby:

1 Używanie Matrixdo tworzenia nowej bitmapy:

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 Zastosowanie RotateAnimationna Viewktóry chcesz obrócić, i upewnij się, że zestaw animacji fillAfter=true, duration=0orazfromDegrees=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"
/>

i nadmuchaj animację w kodzie:

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

danx .. Ale czy nie ma innego sposobu na dynamiczne wykonywanie animacji Rotate w widoku .. mam na myśli dynamiczne ustawianie kąta d ..
rijinrv

działa to lepiej niż zaakceptowana odpowiedź, jeśli obraz, który chcesz obrócić, znajduje się w ListView
Daren,

9

Wiem, że to szalenie późno, ale było to dla mnie pomocne, więc może pomóc innym.

Od interfejsu API 11 można programowo ustawić bezwzględną rotację ImageView przy użyciu imageView.setRotation(angleInDegrees);metody.

Absolutnie mam na myśli, że możesz wielokrotnie wywoływać tę funkcję bez konieczności śledzenia bieżącego obrotu. To znaczy, jeśli obrócę przechodząc 15Fdo setRotation()metody, a następnie wywołam setRotation()ponownie z 30F, obrót obrazu o 30 stopni, a nie 45 stopni.

Uwaga: to faktycznie działa dla dowolnej podklasy obiektu View , nie tylko dla ImageView.


Mój obraz przy obracaniu staje się naturalnie nieco wyższy na stronie. Jak mogę to odłożyć?
Chcę wiedzieć,

Czy Twój obraz jest prawidłowo wyśrodkowany? Jeśli masz nierówną ilość przejrzystości obrazu, obrót może spowodować, że pojawią się zmiany pozycji podczas obracania
thomaspsk

Żaden człowiek, gdy obraz się obraca, wykorzystuje oś. Wyobraź sobie telefon komórkowy w pozycji pionowej na dłoni, a teraz obróć go do pozycji poziomej. Już nie dotyka twojej dłoni. Więc jest spacja ... Ale rozwiązałem to za pomocą setPivotX ()
I Wanna Know

5

To jest moja implementacja RotatableImageView . Użycie jest bardzo proste: wystarczy skopiować attrs.xml i RotatableImageView.java do projektu i dodać RotatableImageView do układu. Ustaw żądany kąt obrotu na przykładzie: parametr kąta .

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

Jeśli masz problemy z wyświetlaniem obrazu, spróbuj zmienić kod w metodzie RotatableImageView.onDraw () lub użyj metody draw ().


1
Bardzo pomocne. Dzięki za udostępnienie!
Stefan Hoth,

Otrzymałem NullPointerException podczas korzystania z RotatableImageView. protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {int w = getDrawable (). getIntrinsicWidth (); ...} BTW, użyłem go w kodzie (i mam podany domyślny obraz), a nie w xml.
RRTW

ten imageView ma dziwne problemy, gdy jest używany w gridView. staje się niewidoczny, dopóki nie przewiniesz.
programista Androida


3

Ponadto, jeśli chcesz obrócić ImageView o 180 stopni w pionie lub w poziomie, możesz użyć scaleYlub scaleXwłaściwości i ustawić je na -1f. Oto przykład Kotlina:

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

1f value służy do powrotu ImageView do normalnego stanu:

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

2

Mam na to rozwiązanie . Właściwie jest to rozwiązanie problemu, który pojawia się po obróceniu (prostokątny obraz nie pasuje do ImagView), ale obejmuje również twój problem. Chociaż to rozwiązanie ma animację na lepsze lub na gorsze

    int h,w;
    Boolean safe=true;

Pobranie parametrów imageView nie jest możliwe przy inicjalizacji działania Aby to zrobić skorzystaj z tego rozwiązania LUB ustaw wymiary po kliknięciu przycisku Jak ten

    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 
       }

I kod do uruchomienia, gdy chcemy obrócić 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();
        }
    });

To rozwiązanie jest wystarczające do rozwiązania powyższego problemu, chociaż zmniejszy to imageView nawet jeśli nie jest to konieczne (gdy wysokość jest mniejsza niż szerokość) .Jeśli ci to przeszkadza, możesz dodać kolejny operator trójskładnikowy wewnątrz scaleX / scaleY.


2

Myślę, że najlepsza metoda :)

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

2

Obróć obraz w systemie Android z opóźnieniem:

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

1

spróbuj tego na niestandardowym widoku

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

oto dobre rozwiązanie do umieszczania obróconego elementu rysunkowego dla 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;
}

stosowanie:

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

inna alternatywa:

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

również, jeśli chcesz obrócić bitmapę, ale boisz się OOM, możesz użyć rozwiązania NDK, które tutaj stworzyłem


1

Jeśli chcesz tylko wizualnie obrócić widok, możesz użyć:

iv.setRotation(float)

1

Dla Kotlina,

mImageView.rotation = 90f //angle in float

Spowoduje to obrócenie imageView zamiast obracania obrazu

Ponadto, chociaż jest to metoda w Viewklasie. Możesz więc prawie obrócić dowolny widok, używając go.



0

Innym możliwym rozwiązaniem jest utworzenie własnego niestandardowego widoku obrazu (powiedzmy RotateableImageView extends ImageView) ... i zastąpienie onDraw (), aby obrócić płótno / mapy bitowe przed ponownym przeniesieniem na płótno. Nie zapomnij przywrócić płótna.

Ale jeśli zamierzasz obrócić tylko jedno wystąpienie widoku obrazu, Twoje rozwiązanie powinno być wystarczająco dobre.


0

bez matrycy i animowane:

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

0

po prostu napisz to w swoim 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

Wypróbuj ten kod w 100% działający;

Kliknij przycisk obracania i napisz ten kod:

        @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

Zamiast konwertować obraz do mapy bitowej, a następnie obracać go, spróbuj obrócić bezpośredni widok obrazu, jak w poniższym kodzie.

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

Postępuj zgodnie z poniższą odpowiedzią, aby uzyskać ciągłą rotację widoku obrazu

int i=0;

Jeśli kliknięto przycisk obracania

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

0

jeśli chcesz obrócić obraz o 180 stopni, umieść te dwie wartości w tagu imageview: -

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

Wyjaśnienie: - scaleX = 1 i scaleY = 1 reprezentują stan normalny, ale jeśli ustawimy -1 na właściwości scaleX / scaleY, to zostanie obrócona o 180 stopni


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

jak używać?

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

Możesz po prostu użyć atrybutu obracania ImageView

Poniżej znajduje się atrybut z ImageView ze szczegółami ze źródła Androida

<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.