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);
rijinrv
źródło
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
znajdź odpowiedź tutaj. stackoverflow.com/a/52983423/5872337
Geet Thakur

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.

Aks
źródło
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

Frolik
źródło
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.

Oleksiy
źródło
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);
Rotemmiz
źródło
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.

Tomaszpsk
źródło
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 ().

petrnohejl
źródło
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
5

Można to również zrobić w ten sposób: -

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

dostałem się stąd.

Debasish Ghosh
źródło
Dzięki! To bardzo łatwe i szybkie
zinonX
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
Yamashiro Rion
źródło
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.

Gaurav Chaudhari
źródło
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);
        }
    });
Trk
źródło
2

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

imgSplash.animate().rotationBy(360f).setDuration(3000).setInterpolator(new LinearInterpolator()).start();
Aftab Alam
źródło
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);
    }
}

jeet.chanchawat
źródło
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

programista Androida
źródło
1

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

iv.setRotation(float)
mgm
źródło
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.

Aziz
źródło
0

Niestety, nie sądzę. MatrixKlasa jest odpowiedzialna za wszystkich manipulacji obrazu, czy to obracanie, kurczy / rośnie, wypaczenia, itp

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

Przepraszam, ale nie mogę wymyślić alternatywy. Może ktoś inny mógłby to zrobić, ale kiedy musiałem manipulować obrazem, korzystałem z Matrixa.

Powodzenia!

roboguy12
źródło
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.

Navin Ilavarasan
źródło
0

bez matrycy i animowane:

{
    img_view = (ImageView) findViewById(R.id.imageView);
    rotate = new RotateAnimation(0 ,300);
    rotate.setDuration(500);
    img_view.startAnimation(rotate);
}
user4747884
źródło
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); 
Świat rozrywki
źródło
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);
            }
        }
Gaurav Sharma
źródło
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);
SWAPDROiD
źródło
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;
Harish Reddy
źródło
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

Prashant Kumar
źródło
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);
   }
}
Amir Hosseinzadeh
źródło
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" />
JB-
źródło