Android: How to rotate a bitmap on a center point

AndroidMatrixBitmapCenterImage Rotation

Android Problem Overview


I've been looking for over a day for a solution to this problem but nothing helps, even the answers here. Documentation doesn't explain anything too.

I am simply trying to get a rotation in the direction of another object. The problem is that the bitmap is not rotated around a fixed point, but rather around the bitmaps (0,0).

Here is the code I am having troubles with:

  Matrix mtx = new Matrix();
  mtx.reset();
  mtx.preTranslate(-centerX, -centerY);
  mtx.setRotate((float)direction, -centerX, -centerY);
  mtx.postTranslate(pivotX, pivotY);
  Bitmap rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0, spriteWidth, spriteHeight, mtx, true);
  this.bitmap = rotatedBMP;

The weird part is, it doesn't matter how I change the values within pre/postTranslate() and the float arguments in setRotation(). Can someone please help and push me in the right direction? :)

Android Solutions


Solution 1 - Android

I hope the following sequence of code will help you:

Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight, config);
Canvas canvas = new Canvas(targetBitmap);
Matrix matrix = new Matrix();
matrix.setRotate(mRotation,source.getWidth()/2,source.getHeight()/2);
canvas.drawBitmap(source, matrix, new Paint());

If you check the following method from ~frameworks\base\graphics\java\android\graphics\Bitmap.java

public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
        Matrix m, boolean filter)

this would explain what it does with rotation and translate.

Solution 2 - Android

Edited: optimized code.

public static Bitmap RotateBitmap(Bitmap source, float angle)
{
      Matrix matrix = new Matrix();
      matrix.postRotate(angle);
      return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}

To get Bitmap from resources:

Bitmap source = BitmapFactory.decodeResource(this.getResources(), R.drawable.your_img);

Solution 3 - Android

I came back to this problem now that we are finalizing the game and I just thought to post what worked for me.

This is the method for rotating the Matrix:

this.matrix.reset();
this.matrix.setTranslate(this.floatXpos, this.floatYpos);
this.matrix.postRotate((float)this.direction, this.getCenterX(), this.getCenterY()); 

(this.getCenterX() is basically the bitmaps X position + the bitmaps width / 2)

And the method for Drawing the bitmap (called via a RenderManager Class):

canvas.drawBitmap(this.bitmap, this.matrix, null);

So it is prettey straight forward but I find it abit strange that I couldn't get it to work by setRotate followed by postTranslate. Maybe some knows why this doesn't work? Now all the bitmaps rotate properly but it is not without some minor decrease in bitmap quality :/

Anyways, thanks for your help!

Solution 4 - Android

You can also rotate the ImageView using a RotateAnimation:

RotateAnimation rotateAnimation = new RotateAnimation(from, to,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
				0.5f);
rotateAnimation.setInterpolator(new LinearInterpolator());
rotateAnimation.setDuration(ANIMATION_DURATION);
rotateAnimation.setFillAfter(true);

imageView.startAnimation(rotateAnimation);

Solution 5 - Android

You can use something like following:


Matrix matrix = new Matrix();
matrix.setRotate(mRotation,source.getWidth()/2,source.getHeight()/2);
RectF rectF = new RectF(0, 0, source.getWidth(), source.getHeight());
matrix.mapRect(rectF);
Bitmap targetBitmap = Bitmap.createBitmap(rectF.width(), rectF.height(), config);
Canvas canvas = new Canvas(targetBitmap);
canvas.drawBitmap(source, matrix, new Paint());

Solution 6 - Android

Look at the sample from Google called Lunar Lander, the ship image there is rotated dynamically.

Lunar Lander code sample

Solution 7 - Android

I used this configurations and still have the problem of pixelization :

Bitmap bmpOriginal = BitmapFactory.decodeResource(this.getResources(), R.drawable.map_pin);
		Bitmap targetBitmap = Bitmap.createBitmap((bmpOriginal.getWidth()),
				(bmpOriginal.getHeight()), 
				Bitmap.Config.ARGB_8888);
		Paint p = new Paint();
		p.setAntiAlias(true);
		
		Matrix matrix = new Matrix();		
		matrix.setRotate((float) lock.getDirection(),(float) (bmpOriginal.getWidth()/2),
				(float)(bmpOriginal.getHeight()/2));
		
		RectF rectF = new RectF(0, 0, bmpOriginal.getWidth(), bmpOriginal.getHeight());
		matrix.mapRect(rectF);
		
		targetBitmap = Bitmap.createBitmap((int)rectF.width(), (int)rectF.height(), Bitmap.Config.ARGB_8888);

		
		Canvas tempCanvas = new Canvas(targetBitmap); 
		tempCanvas.drawBitmap(bmpOriginal, matrix, p);

Solution 8 - Android

matrix.reset();
matrix.setTranslate( anchor.x, anchor.y );
matrix.postRotate((float) rotation , 0,0);
matrix.postTranslate(positionOfAnchor.x, positionOfAnchor.x);
c.drawBitmap(bitmap, matrix, null);	

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStefanView Question on Stackoverflow
Solution 1 - AndroidSudar NimalanView Answer on Stackoverflow
Solution 2 - AndroidArvisView Answer on Stackoverflow
Solution 3 - AndroidSteView Answer on Stackoverflow
Solution 4 - AndroidMacarseView Answer on Stackoverflow
Solution 5 - AndroidSudar NimalanView Answer on Stackoverflow
Solution 6 - AndroidspriteView Answer on Stackoverflow
Solution 7 - AndroidMSaudiView Answer on Stackoverflow
Solution 8 - AndroidLouie AlmedaView Answer on Stackoverflow