简体   繁体   中英

How to rotate a bitmap on canvas without deform it on Android

I'm rotating a bitmap on the canvas using a matrix as follows:

public void drawRotatedPixmap(Bitmap bitmap, int x, int y, int srcX, int srcY, int srcWidth, int srcHeight, int degrees)
{
    srcRect.left = srcX;
    srcRect.top = srcY;
    srcRect.right = srcX + srcWidth;
    srcRect.bottom = srcY + srcHeight;

    dstRect.left = x;
    dstRect.top = y;
    dstRect.right = x + srcWidth;
    dstRect.bottom = y + srcHeight;

    matrix.reset();
    matrix.setRotate(degrees, x+srcWidth/2, y+srcHeight/2);

    canvas.setMatrix(matrix);               
    canvas.drawBitmap(bitmap, srcRect, dstRect, null);
    canvas.setMatrix(null);
}

The original bitmap image is quite pixelated and rotating it I get this:

在此处输入图片说明

By this way the image is rescaling and is quite noticeable at the edges. The result I would get is the following:

在此处输入图片说明

It is posibile do this by drawing on the canvas or should I use openGL?

Note: sprite image is only for testing and taken from google

To get higher quality, use a filtered paint:

Paint filterPaint = new Paint();
filterPaint.setFilterBitmap(true);
canvas.drawBitmap(bitmap, srcRect, dstRect, filterPaint);

The approach you're taking is absolutely fine. However it looks to me like the original graphic is already fuzzy - I daresay it has been a JPG at some point in its life. Note in particular that the edges to the black borders are anti-aliased - they should be black pixels and white pixels but no grey ones.

I believe the rotation algorithm uses sampling to produce the output - this sampling algorithm is interacting with the fuzzy edge producing the undesirable visual artefacts. I bet it will be great if you try again with a sharp original.

There is one more thing to consider: Using a small bitmap and upscaling with rotation. This might go against the advice of other responders, but bear with me for a minute.

The typical scaling algorithm used is typically bi-linear interpolation - it's great for photos but pixelated images look horribly soft. However there are a few other algorithms - go to Wiki: Image Scaling and look at the hqx. This is an example of bi-linear vs. HQX in the game space:

这个游戏

If this is acceptable, then we have to go to OpenGL, because the Android Canvas and Bitmap functions don't support these algorithms. Potentially a lot of work, but maybe worth your while.

I don't think you can really avoid the pixilating effects with bitmap images. You might reduce the effect by having a sprite drawn at a very high resolution, doing the rotation and then scale the image down. If you have a vector (SVG) version of the image you could rotate that before converting to a bitmap and store a bunch of rotated versions.

You should be able to rotate by 90 without pixilating effects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM