使用Android中的Matrix缩放和旋转位图

Tar*_*nfx 31 graphics android

我试图在创建最终位图之前在单个操作中进行缩放和旋转但是preRotate,postConcat似乎不起作用.

Bitmap bmp = ... original image ...

Matrix m = new Matrix()
m.setScale(x, y);
m.preRotate(degrees, (float) width / 2, (float) height / 2);

Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true);
Run Code Online (Sandbox Code Playgroud)

它只适用比例而不是旋转.

PFR*_*LIM 39

给出了答案,但为了让任何人都能更清楚地了解这一点:

1)如果你想在你的位图中执行一次转换,你可以使用SET(setRotate,setScale等).

但请注意,任何对"set"方法的调用都会覆盖其他转换.这就像一个新矩阵.这就是为什么OP的轮换不起作用的原因.这些调用不是逐行执行的.就像它们被安排在GPU运行时在绘制新位图时完成.就像解析你的矩阵一样,GPU旋转它,然后,创建了一个缩放的新矩阵,忽略了之前的矩阵.

2)如果你想进行多次转换,那么你必须使用"pre"或"post"方法.

例如,postRotate和preRotate之间有什么区别?好吧,这个矩阵数学的东西不是我的力量,但我所知道的是图形卡使用矩阵乘法进行这些变换.它看起来更有效率.而且就我从学校记得的那样,当乘法矩阵时,顺序非常重要.AXB!= BX A.因此,缩放矩阵然后旋转它与旋转不同然后缩放它.

BUUUUT,就屏幕的最终结果而言,我们高级程序员通常不需要知道这些差异.GPU确实如此.

好吧,在极少数情况下,当你执行非常复杂的矩阵操作,结果不是你所期望的或性能很糟糕,你需要深入了解这些方法来修复你的代码,那么,android文档不能太多无论如何帮助.相反,一本好的线性代数书将是你最好的朋友.;)

  • "AXB!= BX A. Sp,缩放矩阵然后旋转它与旋转不同然后缩放它.[...] BUUUUT [...]屏幕中的最终结果是相同的" - 用于记录,旋转和缩放关于单点做通勤(AB = BA); 当且仅当他们通勤时,他们看起来一样.高级程序员确实需要了解这一点.示例:3D中的旋转不通勤 - 尝试翻转书籍. (3认同)

Ars*_*war 36

请查看此链接了解详情

http://www.anddev.org/resize_and_rotate_image_-_example-t621.html

这是代码

public class Bitmaptest extends Activity {
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        LinearLayout linLayout = new LinearLayout(this);

        // load the origial BitMap (500 x 500 px)
        Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
               R.drawable.android);

        int width = bitmapOrg.getWidth();
        int height = bitmapOrg.getHeight();
        int newWidth = 200;
        int newHeight = 200;

        // calculate the scale - in this case = 0.4f
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;

        // createa matrix for the manipulation
        Matrix matrix = new Matrix();
        // resize the bit map
        matrix.postScale(scaleWidth, scaleHeight);
        // rotate the Bitmap
        matrix.postRotate(45);

        // recreate the new Bitmap
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
                          newWidth, newHeight, matrix, true);

        // make a Drawable from Bitmap to allow to set the BitMap
        // to the ImageView, ImageButton or what ever
        BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);

        ImageView imageView = new ImageView(this);

        // set the Drawable on the ImageView
        imageView.setImageDrawable(bmd);

        // center the Image
        imageView.setScaleType(ScaleType.CENTER);

        // add ImageView to the Layout
        linLayout.addView(imageView,
                new LinearLayout.LayoutParams(
                      LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT
                )
        );

        // set LinearLayout as ContentView
        setContentView(linLayout);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是对的.创建位图时使用原始宽度和高度.更改位图resizedBitmap = Bitmap.createBitmap(bitmapOrg,0,0,newWidth,newHeight,matrix,true); to Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg,0,0,width,height,matrix,true); 否则它将简单地关闭部分图像并忽略矩阵postScale.setScale. (14认同)