Rotate a bitmap and bitmap is getting blur in android

I am developing an android game. and in this I want to move an object along a Bezier path.

my object is rotating with some angle on this curve.

I used this piece of code:

public void update() {

// check collision with bottom wall if heading down
if (droid.getSpeed().getyDirection() == Speed.DIRECTION_DOWN
&& droid.getY() + droid.getBitmap().getHeight() / 2 >= getHeight()/2 &&
droid.getY() + droid.getBitmap().getHeight() / 2 <= getHeight()/2+ 100 ) {

int pointX[], pointY[];
pointX = new int[4];
pointY = new int[4];
int  X , Y;

pointX[0] = getWidth()/2;
pointX[1] = getWidth()/2 + 50;
pointX[2] = getWidth()/2 + 25;
pointX[3] = getWidth()/2;
pointY[0] = getHeight()/2;
pointY[1] = getHeight()/2 + 25;
pointY[2] = getHeight()/2 + 50;
pointY[3] = getHeight()/2 + 100;

Log.i(TAG, "In the While Zone of Last Half Zone");
X = (int) ((pointX[3] * u * u * u) + (3 * pointX[2] * u * u * (1-u)) + (3 * pointX[1] * u * (1-u) * (1-u)) +
(pointX[0] * (1-u) * (1-u) * (1-u)));

Y = (int) ((pointY[3] * u * u * u) + (3 * pointY[2] * u * u * (1-u)) + (3 * pointY[1] * u * (1-u) * (1-u)) +
(pointY[0] * (1-u) * (1-u) * (1-u)));

Log.i(TAG+" Value of X: ", Double.toString(X));
Log.i(TAG+" Value of Y: ", Double.toString(Y));

double deltaX = X - droid.getX();
double deltaY = Y - droid.getY();

Log.i("deltaX :", Double.toString(deltaX));
Log.i("deltaY :", Double.toString(deltaY));

double angle = Math.atan2(deltaY, deltaX)  ;
Log.i(TAG+" Angle: ", Double.toString(angle));
Matrix mtx = new Matrix();
mtx.preRotate((float) angle);
mtx.postScale(1, 1);

Bitmap rotatedBMP = Bitmap.createBitmap(droid.getBitmap(), droid.getX(), droid.getY(),  X - droid.getX(), Y - droid.getY(), mtx, true);
droid.setBitmap(rotatedBMP);
droid.curveUpdate(X, Y);
u = u + 0.001;
Log.i(TAG+" Value of U: ", Double.toString(u));

}
// check collision with top wall if heading up

// Update the lone droid
else{
droid.update();
}

}


my object is moving and rotating as i supposed but image is getting blur. am not getting why is so.

Please suggest what can be the problem.

Thanks.

• Images might help.. – Jari Komppa Dec 22 '11 at 11:48
• @Jari Komppa: images might help??? would you please elobarate – Romi Dec 22 '11 at 12:43
• some screenshots of what's going on might help understand your problem. – Jari Komppa Dec 22 '11 at 13:43
• It looks like maybe you're setting the bitmap to the rotated bitmap. Try using the original image for each rotation. If you're rotating from 10 degrees to 20 degrees, don't take the 10 degree image and rotate it 10 more degrees. That just blurs the blurred image even more. Instead, rotate the original by 20, and this will eliminate accumulated blur. – Steve Blackwell Dec 23 '11 at 7:45

Rotating a bitmap will always result in a blurred image - there is no way around that. (Except for rotations of 90/270/360 degrees.) Even high-end programs like photoshop cannot work around the issue - but they mitigate it.

First, a bitmap stores its information pixel per pixel. So you have a large grid of pixels that composes the image. To see it in action, open you favorite bitmap painting tool and zoom in to the max. At that point, you can see the individual pixel that composes an image.

Those pixels are always arranged in a grid of horizontal rows and vertical columns. Always vertical and horizontal. This is where the rotation problem arise...

The image above shows what is going on. In the top left you have an example bitmap. Notice that its rows and column are horizontal and vertical. In the bottom right, you first have the same bitmap, with a slight rotation. But as I explained earlier, you cannot leave rows non-horizontal, so you have to transcribe the rotated image to an horizontal/vertical grid (shown in red in the image).

By the way, each square represents a pixel. As you can see the pixels of the red grid do not align cleanly with the bitmap behind. (In fact the bitmap is now a little bit larger than it used to be - another effect of the rotation.) To figure how each of the grid pixel should be colored, you take an average of the pixels in the bitmap overlapping the pixel you want to draw.

Which, of course, results is colors that are slightly different and therefore a blurred image.

The technique you use to average the color are varied and some result it much much better images, but they also take longer to evaluate.

I suspect that the Android .createBitmap image does do a good job at it. You have a few solutions:

• there may be a different library for bitmap manipulation for Android
• use opengl quad's, they do a good job at rotations
• use image magick to create sprites of pre-rotated images

If you are not using OpenGL, then most games load sprite sheets with rotation already done (see other image).. You only need a quadrant worth of rotation pre-calculated. It saves memory and you can rotate on the fly to 90/180/270 without loosing quality to cover the other 4 quadrant (going back to the first figure, notice that the grids will align perfectly with rotations of 90/180/270 degrees).

I'm not an android developer but after taking a quick look in to the documentation I will try to speculate...

The last parameter of Bitmap.createBitmap is filter. If it's set then the function will do bi-linear or tri-linear (if there is scale) filter, which will look like blur. I'm afraid that if you disable this you will like the result even less. My guess is that you are using some pixelated art style that will just not work well.

If a pixelated art style is what you are using and is what you want I suggest that you manually draw a few frames on different angles and pick the closest one depending of the normal of the curve.

Note: Bi-linear and tri-linear filtering are what games use these days but the textures should not be super high frequency. Like if you make a checkerboard texture with pixel size squares after transformation it will look really bad no matter what hardware or drawing API you are using.