0
votes

I'm having a problem getting a bitmap to rotate properly. I have a SurfaceView with multiple bitmaps on it. These bitmaps exist within an arraylist and using a for loop I call canvas.drawBitmap for each one in the onDraw method.

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.BLACK);

    for (int i = 0; i < jumper.size(); i++) {
        canvas.drawBitmap(jumper.get(i).getGraphic(), jumper.get(i)
                .getCoordinates().getX(), jumper.get(i).getCoordinates()
                .getY(), null);
    }
}

I am attempting to have the user select a specific bitmap (one of many) and then have that bitmap rotate while the user drags his finger across the screen. So here is the rotation code. For now I'm just using the default android icon (72x72px) existing at a random position somewhere near the center of the screen.

private void rotateJumper(int direction) {
    Matrix matrix = new Matrix();
    Bitmap source = jumper.get(selectedJumperPos).getGraphic();
    matrix.postRotate(direction, source.getWidth() / 2, 
            source.getHeight() / 2);
    int x = 0;
    int y = 0;
    int width = 72;
    int height = 72;
    Bitmap tempBitmap = Bitmap.createBitmap(source, x, y, width, height,       
            matrix, true);
    jumper.get(selectedJumperPos).setGraphic(tempBitmap);
}

The integer direction is either +1 or -1 depending on the direction of the finger drag. So the image should rotate 1 degree for every MotionEvent.ACTION_MOVE event.

Here are the problems:

  1. The image doesn't rotate about the image center. CW rotations center about the bottom left corner. CCW rotations center about the top right corner.
  2. Since it isn't rotating about the center, the image rotates outside its initial bounds and eventually disappears.
  3. The image gets blurry as it rotates.

Any help you could give me would be greatly appreciated.

Thanks!

2

2 Answers

0
votes

Use the matrix to draw the existing bitmap to the canvas rather than creating a new bitmap:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.BLACK);

    for (int i = 0; i < jumper.size(); i++) {
        canvas.drawBitmap(jumper.get(i).getGraphic(), jumper.get(i).getMatrix(), null);
    }
}

private void rotateJumper(int direction) {
    Matrix matrix = jumper.get(selectedJumperPos).getMatrix();
    if(matrix == null) {
        matrix = new Matrix();
        matrix.setTranslate(jumper.get(...).getCoord...().getX(), jumper.get(..).getCoord...().getY());
        jumper.get(selectedJumperPos).setMatrix(matrix);
    }
    Bitmap source = jumper.get(selectedJumperPos).getGraphic();
    matrix.postRotate(direction, source.getWidth() / 2, 
            source.getHeight() / 2);

}
0
votes

Pardon me for rather offtopic answer, but your for -loop caught my attention. It might be possible to write it in 'more readable' format;

for (YourJumperItem item : jumper) {
    canvas.drawBitmap(
        item.getGraphic(), item.getCoordinates().getX(),
        item.getCoordinates().getY(), null );
}

Where YourJumperItem is the class type your jumper -array contains. Unfortunately can't say much about rotating Bitmaps, am just promoting this handy way of writing for -loops.