【问题标题】:How to rotate a bitmap on canvas without deform it on Android如何在画布上旋转位图而不在Android上使其变形
【发布时间】:2026-01-10 01:15:01
【问题描述】:

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

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

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

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

可以通过在画布上绘图来做到这一点,还是应该使用 openGL?

注意:精灵图片仅供测试,取自谷歌

【问题讨论】:

    标签: java android canvas bitmap rotation


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      我相信旋转算法使用采样来产生输出 - 这种采样算法正在与模糊边缘交互,从而产生不受欢迎的视觉伪影。我敢打赌,如果你用锐利的原件再试一次,那就太好了。

      还有一件事要考虑:使用 small 位图并通过旋转放大。这可能会违背其他响应者的建议,但请耐心等待。

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

      如果这是可以接受的,那么我们必须使用 OpenGL,因为 Android 的 Canvas 和 Bitmap 函数不支持这些算法。可能需要做很多工作,但也许值得您花时间。

      【讨论】:

        【解决方案3】:

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

        您应该能够旋转 90 度而不会产生像素化效果。

        【讨论】:

          最近更新 更多