How to rotate a bitmap in Android about images center smoothly without oscillatory movement

Anshul picture Anshul · Nov 15, 2012 · Viewed 13.9k times · Source

I want to rotate a bitmap image based on user click by 10 deg. Following numerous stackoverflow and google answers, I tried various combinations of Matrix rotation.

However the image doesn't really rotate as expected and gives a jittery view of rotation + oscillation about canvas center. To test I am increasing rotation angle by 10 deg (instead of clicks) each time object's draw method is called. The image is a symmetrical circle [64x64 enclosing rectangle] and I expect it to rotate at center of screen about it's own center like a wheel, but it rotates and moves diagonally towards right-down and moves back upto center of screen in an oscillatory fashion.

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

 }

Answer

yoah picture yoah · Nov 15, 2012

Here is an example. I broke it to 3 steps. The first translate moves the bitmap so that it's center is at 0,0 Then a rotation, and finally move the bitmap center to where you want it on the canvas. You don't need the second bitmap.

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

As an optimization, create the Matrix once outside this method and replace the creation with a call to matrix.reset()