图像在旋转时会改变大小。我怎么阻止这个?

时间:2011-03-13 04:43:11

标签: android bitmap transformation

我正在为Android制作游戏,我需要旋转图像。当我旋转它时,它的尺寸会发生变化。例如,当它旋转45度(它是正方形,但我希望这适用于任何矩形,因此这是一个更通用的解决方案)它的宽度和高度成为对角线的长度,它比原始长度长。在一些代数之后,你可以得出比例因子是sqrt(2)。但我知道旋转位图的唯一方法是使用矩阵。例如:

matrix.postRotate(degrees);
rotated = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);

使用此方法,位图的大小保持不变,因此要使图像内容中的旋转图像适合缩小。这导致我的问题。

我现在应该工作但运行时却没有。可能是因为它过于复杂,从来没有那么少,这就是:

     float totalRotated = 0;

public void rotate(float degrees){
    if(mBitmap != null){
        float increment = (float)((mBitmap.getWidth()/45.0)*(Math.sqrt(2)-1));
        totalRotated += degrees;
        totalRotated -= (float)((int)totalRotated/360)*360;
        matrix.reset();
        matrix.setRotate(totalRotated);
        rotated = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
        rotated = Bitmap.createScaledBitmap(rotated, (int)(mBitmap.getWidth()+(((Math.abs(Math.abs(((int)totalRotated%90)-45)-45)))*increment)), (int)(mBitmap.getHeight()+(((Math.abs(Math.abs(((int)totalRotated%90)-45)-45)))*increment)), true);
    }
}

使用Log.d函数,我能够确定最后一个语句中设置的维度是我期望的,但图像不会改变大小。由于这甚至不起作用,我需要一个更好的方法来做到这一点或一种方法来修复我的方法。我的方法也适用于正方形。那么,我该怎么做呢?

编辑:  我的方法确实有效,我只是没有调用setBounds()这不是唯一的方法,但这样效率很低。

2 个答案:

答案 0 :(得分:1)

目前还不清楚你在寻找什么,所以这里有一个基于你的功能,试图计算新位图的正确宽度和高度,并通过只创建一个位图来进行旋转。

float totalRotated = 0;

public void rotate(float degrees){
    if(mBitmap != null){
        // compute the absolute rotation
        totalRotated = (totalRotated + degrees) % 360;
        // precompute some trig functions
        double radians = Math.toRadians(totalRotated);
        double sin = Math.abs(Math.sin(radians));
        double cos = Math.abs(Math.cos(radians));
        // figure out total width and height of new bitmap
        int newWidth = mBitmap.getWidth() * cos + mBitmap.getHeight() * sin;
        int newHeight = mBitmap.getWidth() * sin + mBitmap.getHeight() * cos;
        // set up matrix
        matrix.reset();
        matrix.setRotate(totalRotated);
        // create new bitmap by rotating mBitmap
        rotated = Bitmap.createBitmap(mBitmap, 0, 0,
                                      newWidth, newHeight, matrix, true);
    }
}

答案 1 :(得分:0)

我尝试了 Gabe 的解决方案,但遇到了与 Ramesh 和 Regis 相同的错误。这对我有用:

        double radians = Math.toRadians(totalRotated);
        double sin = Math.abs(Math.sin(radians));
        double cos = Math.abs(Math.cos(radians));
        // figure out total width and height of new bitmap
        final int width = mBitmap.getWidth();
        final int height = mBitmap.getHeight();
        final int newWidth = (int) (width * cos + height * sin);
        final int newHeight = (int) (width * sin + height * cos);
        // set up matrix
        final Matrix tf = new Matrix();
        tf.postRotate((float) Math.toDegrees(radians), width / 2, height / 2);
        tf.postTranslate(
            (newWidth - width) / 2,
            (newHeight - height) / 2);
        // create new bitmap by rotating mBitmap with canvas
        final Bitmap rotatedBmp = Bitmap.createBitmap(
            newWidth, newHeight, Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(rotatedBmp);
        canvas.drawBitmap(mBitmap, tf, null);