如何在画布上旋转位图而不在Android上对其进行变形

时间:2014-03-22 20:05:33

标签: java android canvas bitmap rotation

我正在使用矩阵在画布上旋转位图,如下所示:

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);
}

原始位图图像非常像素化并旋转它我得到了这个:

enter image description here

通过这种方式,图像重新缩放,并且在边缘处非常明显。 我得到的结果如下:

enter image description here

通过在画布上画画或者我应该使用openGL来做到这一点吗?

注意:精灵图片仅用于测试并取自谷歌

3 个答案:

答案 0 :(得分:4)

要获得更高的质量,请使用过滤后的油漆:

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

答案 1 :(得分:3)

你采取的方法绝对没问题。然而,在我看来,原始图形已经模糊了 - 我敢说它在它的生命中的某个时刻是JPG。请特别注意黑色边框的边缘是消除锯齿的 - 它们应该是黑色像素和白色像素,但不是灰色像素。

我认为旋转算法使用采样来产生输出 - 这种采样算法与模糊边缘相互作用,产生不希望的视觉假象。我敢打赌,如果你再用一张锋利的原版再试一次会很棒。

还有一件事需要考虑:使用位图并使用旋转升级。这可能违背其他响应者的建议,但请耐心等待一分钟。

使用的典型缩放算法通常是双线性插值 - 它非常适合照片,但像素化图像看起来非常柔和。但是还有一些其他算法 - 转到Wiki: Image Scaling并查看hqx。这是游戏领域中双线性与HQX的一个例子:

this game

如果这是可以接受的,那么我们必须转到OpenGL,因为Android Canvas和Bitmap功能不支持这些算法。可能有很多工作,但也许值得你花时间。

答案 2 :(得分:1)

我认为你不能真正避免使用位图图像进行像素化效果。您可以通过以非常高的分辨率绘制精灵,进行旋转然后缩小图像来减少效果。如果你有一个矢量(SVG)版本的图像,你可以在转换为位图之前旋转它并存储一堆旋转版本。

你应该可以在没有像素化效果的情况下旋转90度。