6

I'm struggling to draw a rotating bitmap around its center and do the rotating without resizing the bitmap. I'm drawing all my sprites to the screen via a game thread, so I'm looking for a solution that incorporates the original bitmap and not the canvas.

Thanks in advance.

This is my code so far, it turns a bitmap around its center, yet resizes it.

i = i + 2;
            transform.postRotate(i, Assets.scoresScreen_LevelStar.getWidth()/2, Assets.scoresScreen_LevelStar.getHeight()/2);
            Bitmap resizedBitmap = Bitmap.createBitmap(Assets.scoresScreen_LevelStar, 0, 0, Assets.scoresScreen_LevelStar.getWidth(), Assets.scoresScreen_LevelStar.getHeight(), transform, true);

            game.getGraphics().getCanvasGameScreen().drawBitmap(resizedBitmap, null, this.levelStar.getHolderPolygons().get(0), null);

Update:

I've noticed this isn't as easy as it sounds. My rotating code is not the problem. The bitmap rotates, yet the dst rect will also have to increase/decrease depending on the angle of rotation, or else the bimap will appear smaller, since it's drawn into a fixed dst rect. So I'm guessing I'll have to develop some method that will return a dst rect. So the methods needed to rotate a bitmap without appeared resizing:

public static Bitmap rotateBitmap(Bitmap bitmap, int rotation) // I've got this method working

and

public static Rect rotateRect(Rect currentDst, int rotation) // Don't got this

I understand this will require some math (trig), anyone up for the challenge? :P

Luke Taylor
  • 9,481
  • 13
  • 41
  • 73

2 Answers2

8

You should draw the bitmap using the Matrix class. Below is a very basic idea assuming that you want to rotate an image inside of a "Ship" class. You update the current position Matrix inside the update method. In the onDraw() you draw the bitmap using the newly updated position Matrix. This will draw the rotated bitmap without resizing it.

public class Ship extends View {

    private float x, y;
    private int rotation;
    private Matrix position;    
    private Bitmap bitmap;

    ...

    @Override
    public void onDraw(Canvas canvas) {
        // Draw the Bitmap using the current position
        canvas.drawBitmap(bitmap, position, null);
    }

    public void update() {
        // Generate a new matrix based off of the current rotation and x and y coordinates.
        Matrix m = new Matrix();
        m.postRotate(rotation, bitmap.getWidth()/2, bitmap.getHeight()/2);
        m.postTranslate(x, y);

        // Set the current position to the updated rotation
        position.set(m);

        rotation += 2;
    }

    ....

}

Hope that helps!

Also keep in mind that generating a new Bitmap object inside you game loop will be resource intensive.

DRiFTy
  • 11,269
  • 11
  • 61
  • 77
  • Could you rewrite, that I can call a static method called rotateBitmap(Bitmap bitmap, int rotation), that will return a Bitmap rotated Bimap object? – Luke Taylor Jul 12 '12 at 09:41
  • the method changes the bitmap that you pass in, so ur private variable "private Bitmap bitmap;" is not rotated. Just do "return bitmap;" and change the method signature. – Aziz Jul 16 '12 at 15:35
0

This worked for me!

I created a method that returns a matrix. The matrix can be used in the following drawing method:

public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)

Here you go! (The parameter shape can be replaced with ease, if you would like that, just leave a comment):

public static Matrix rotateMatrix(Bitmap bitmap, Shape shape, int rotation) {

        float scaleWidth = ((float) shape.getWidth()) / bitmap.getWidth();
        float scaleHeight = ((float) shape.getHeight()) / bitmap.getHeight();

        Matrix rotateMatrix = new Matrix();
        rotateMatrix.postScale(scaleWidth, scaleHeight);
        rotateMatrix.postRotate(rotation, shape.getWidth()/2, shape.getHeight()/2);
        rotateMatrix.postTranslate(shape.getX(), shape.getY());


        return rotateMatrix;

    }

NB: If you want an animated rotation, the rotation parameter will have to be updated with new values every frame eg. 1 then 2 then 3 ...

Luke Taylor
  • 9,481
  • 13
  • 41
  • 73