图像在旋转时会改变大小。我该如何阻止这个?

发布于 2024-10-22 05:31:46 字数 1325 浏览 2 评论 0原文

我正在为 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() 但这不是唯一的方法,这效率很低。

I'm making a game for Android and I need to rotate an image. When I rotate it obviously it's dimensions change. For example when it's rotated 45 degrees (it's square but I'd like this to work for any rectangle so it's a more general solution) it's width and height become the length of the diagonal, which is longer than the original. After some algebra you can work out that the scale factor is sqrt(2). But the only way I know of to rotate a bitmap is with a matrix. Ex:

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

Using this method the size of the bitmap remains constant so to fit the rotated image in the content of the image must shrink. Which causes my problem.

What I have now should work but when run doesn't. Probably because it's overly complex, never the less, here it is:

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

Using the Log.d function I was able to determine that the dimensions set in the last statement are what I expect them to be but the image doesn't change size. Since this doesn't even work, I need a better way to do this or a way to fix my method. Also my method only works for squares. So, how can I do this?

EDIT:
My method does work, I just didn't call setBounds() This can't be the only way to do it though, this is so inefficient.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黯淡〆 2024-10-29 05:31:46

目前尚不清楚您在寻找什么,因此这里有一个基于您的函数,它尝试计算新位图的正确宽度和高度,并通过仅创建一个位图来进行旋转。

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

It's not clear what you're looking for, so here's a function based on yours that attempts to compute the proper width and height of the new bitmap and do the rotation by creating just a single bitmap.

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);
    }
}
撧情箌佬 2024-10-29 05:31:46

我尝试了 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);

I tried Gabe's solution and got the same errors that Ramesh and Regis got. This worked for me:

        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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文