2012-11-15 28 views
7

Chcę obrócić obraz bitmapowy na podstawie kliknięcia użytkownika o 10 stopni. Po licznych odpowiedziach na stackoverflow i google, wypróbowałem różne kombinacje rotacji macierzy.Jak obracać bitmapę w Androidzie o centrum obrazów płynnie bez ruchu oscylacyjnego

Jednak obraz nie obraca się zgodnie z oczekiwaniami i daje niezadowalający widok obrotu + oscylacji wokół środka płótna. Aby przetestować, zwiększam kąt obrotu o 10 stopni (zamiast kliknięć) za każdym razem, gdy wywoływana jest metoda rysowania obiektu. Obraz jest symetrycznym okręgiem [64x64 obejmującym prostokąt] i spodziewam się, że obróci się w centrum ekranu wokół swojego centrum, jak koło, ale obraca się i porusza się po przekątnej w prawo iw dół, i przesuwa się do środka ekranu w oscylacyjny sposób .

public void draw(Canvas canvas) { 
    Matrix matrix = new Matrix(); 

    rotation += 10; 
    float px = this.viewWidth/2; 
    float py = this.viewHeight/2; 
    matrix.setRotate(rotation, bitmap.getWidth()/2, bitmap.getHeight()/2); 
    Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, getImgWidth(), getImgHeight(), matrix, true); 
    canvas.drawBitmap(newbmp, px - (getImgWidth()/2), py - (getImgHeight()/2), null); 

} 

Odpowiedz

18

Oto przykład. Zepsułem go do 3 kroków. Pierwszy tłumacz przesuwa mapę bitową, tak aby jej środek wyniósł 0,0 Następnie obróć, i na koniec przenieś centrum bitmapowe tam, gdzie chcesz na płótnie. Nie potrzebujesz drugiej bitmapy.

Matrix matrix = new Matrix(); 
rotation += 10; 
float px = this.viewWidth/2; 
float py = this.viewHeight/2; 
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2); 
matrix.postRotate(rotation); 
matrix.postTranslate(px, py); 
canvas.drawBitmap(bitmap, matrix, null); 

Jako optymalizacji, tworzyć Matrix raz poza tą metodą i wymienić utworzenie z wezwaniem do matrix.reset()

+2

Wielkie dzięki !. Działa to z przeniesieniem macierzy z metody "rysowania" i zapewnieniem, że macierz nie jest resetowana [daje płynny efekt rotacji]. Użyto także 'matrix.setRotate (rotation, bitmap.getWidth()/2, bitmap.getHeight()/2);' zamiast dwóch pierwszych * metod. – Anshul

+0

Dzięki za tę odpowiedź. Oszczędza mi to dzień. – Siddharth

+0

Jaki jest ten widok tutaj? –

0

trzeba tłumaczyć bitmapę do punktu, 0,0 (lub wyciągnąć go na 0,0) i obrócić go tam, a następnie przełożyć je z powrotem, jako takich:

canvas.save(); 
    canvas.translate(this.viewWidth, this.viewHeight); 
    canvas.rotate(rotation); 
    canvas.drawBitmap(newbmp, -(getImgWidth()/2), -(getImgHeight()/2), null); 
canvas.restore(); 

Tutaj narysuj ją środkiem o wartości 0,0 (jak sądzę), ponieważ kiedy się obrócisz, będzie to około 0,0, a nie środek ekranu, jak mogłoby się wydawać. Jeśli narysujesz środek o wartości 0,0, obróci się on wokół środka mapy bitowej.

Jeśli mój kod nie wyświetli centrum bitmapowego o wartości 0,0, możesz zmienić kod, aby narysować go w środku i będzie działał tak, jak chcesz.

Mam nadzieję, że to pomoże!

+0

:(. Powyższa metoda pogorszyła sprawę. Teraz moje koło przechodzi w prawy dolny róg i oscyluje wokół prawego dolnego rogu, podczas gdy reszta tła i obiektów "wygląda" tak, jak jest. canvas.translate po prostu przesuwa centrum koła – Anshul

+0

To faktycznie działa, jeśli przetłumaczysz 'getImgWidth()/2' i' getImgHeight()/2' zamiast wymiarów widoku. –

0
// x : x coordinate of image position 
// y : y coordinate of image position 
// w : width of canvas 
// h : height of canvas 
canvas.save(); 
canvas.rotate(angle, x + (w/2), y + (h/2)); 
canvas.drawBitmap(image, x, y, null); 
canvas.restore(); 

Kroki są

  1. Zapisz istniejący płótno
  2. Obróć płótno wokół środka mapy bitowej, które można narysować na płótnie o kącie obrotu
  3. Narysuj obraz
  4. przywrócić obraz