Android中的矩阵(Matrix)变换

写在前面:

本篇博文将结合一个简单的Demo,讲解一下如何通过Matrix实现对Bitmap对象的一些简单处理,例如平移,旋转,放缩等。此外还会讲解一下矩阵乘法中的左乘右乘在Android中的代码实现。

一、Matrix类

这里说的Matrix类是位于"android.graphics.Matrix"包下的。它是Android提供的一个矩阵工具类,它本身不能对图像或View进行变换,但它可与其他API结合来控制图形、View的变换,如Canvas。在Matrix类中,提供了一些方法来控制图片变换:

  • setTranslate(float dx,float dy):控制Matrix进行位移。
  • setSkew(float kx,float ky):控制Matrix进行倾斜,kx、ky为X、Y方向上的比例。
  • setSkew(float kx,float ky,float px,float py):控制Matrix以px、py为轴心进行倾斜,kx、ky为X、Y方向上的倾斜比例。
  • setRotate(float degrees):控制Matrix进行depress角度的旋转,轴心为(0,0)。
  • setRotate(float degrees,float px,float py):控制Matrix进行depress角度的旋转,轴心为(px,py)。
  • setScale(float sx,float sy):设置Matrix进行缩放,sx、sy为X、Y方向上的缩放比例。
  • setScale(float sx,float sy,float px,float py):设置Matrix以(px,py)为轴心进行缩放,sx、sy为X、Y方向上的缩放比例。

其中每一个功能又以三个方法为一组,以位移的Translate为例:

  •  setTranslate(float dx,float dy)
  •  preTranslate(float dx,float dy)
  •  postTranslate(float dx,float dy)

其中pre前缀和post前缀分别对应了矩阵乘法中的右乘(前乘) 和左乘(后乘),至于更加详细的部分我会与本文后半部分讲解。

二、通过Matrix实现单矩阵变换

所谓单矩阵变换说的玄乎,其实就是单次变换,比如平移一次或者旋转一次。

2.1.对Bitmap进行放缩

因为单矩阵变换思路都一样,只是采用了不同的set方法去设置矩阵,我就在这里统一说下变换思路:

1.首先要根据变换的情况计算变换后的位图大小,以避免图片变换之后跑出原区域导致显示不全的情况

2.用计算之后的位图创建Canvas实例

3.设置矩阵Matrix

4.开始绘图

5.最后把绘制好的位图设置到ImageView上展示

/**
 * 图片缩放
 * */
private void bitmapScale(float x,float y){
    newBitmap = Bitmap.createBitmap((int) (mBitmap.getWidth() * x),(int) (mBitmap.getHeight() * y), mBitmap.getConfig());
    Canvas canvas = new Canvas(newBitmap);
    Matrix matrix = new Matrix();
    matrix.setScale(x, y);
    //第一个参数为待绘制的bitmap,第二个参数为矩阵,第三个参数为画笔
    canvas.drawBitmap(mBitmap, matrix, mPaint);
    imageView.setImageBitmap(newBitmap);
    mBitmap = newBitmap;
}

上述代码中newBitmap是变换之后的图片,mBitmap是变换之前的图片。Bitmap.createBitmap()方法接收三个参数,依次为宽、高、配置项,这里沿用了原图的配置。最后 mBitmap = newBitmap 是为了使后续变换能够在上一次变换的基础上进行。

2.2.对Bitmap进行旋转

/**
 * 图片旋转
 * */
private void bitmapRotate(float degrees){
    newBitmap = Bitmap.createBitmap(mBitmap.getWidth(),mBitmap.getHeight(),mBitmap.getConfig());
    Canvas canvas = new Canvas(newBitmap);
    Matrix matrix = new Matrix();
    matrix.setRotate(degrees,mBitmap.getWidth()/2,mBitmap.getHeight()/2);
    canvas.drawBitmap(mBitmap, matrix, mPaint);
    imageView.setImageBitmap(newBitmap);
    mBitmap = newBitmap;
}

2.3.对Bitmap进行平移

/**
 * 图片平移
 * */
private void bitmapTranslate(float dx,float dy){
    newBitmap = Bitmap.createBitmap((int)(mBitmap.getWidth()+Math.abs(dx)),(int)(mBitmap.getHeight()+Math.abs(dy)),mBitmap.getConfig());
    Canvas canvas = new Canvas(newBitmap);
    Matrix matrix = new Matrix();
    matrix.setTranslate(dx,dy);
    canvas.drawBitmap(mBitmap,matrix,mPaint);
    imageView.setImageBitmap(newBitmap);
    mBitmap = newBitmap;
}

三、通过Matrix实现多矩阵变换

在讲多矩阵变换之前得明确矩阵乘法的基本性质,需要牢记以下两点:

  • 矩阵乘法满足结合律 (AB)C=A(BC),因此可以任何两个先乘, 自由结合
  • 矩阵乘法大多时候不满足交换律,因此不可以颠倒矩阵的顺序进行乘算

弄清楚矩阵乘法之后,我们再来看set前缀pre前缀以及post前缀变换时的区别,先来看看官方API文档:

public boolean postTranslate (float dx, float dy)

Postconcats the matrix with the specified translation. M' = T(dx, dy) * M

public boolean preTranslate (float dx, float dy)

Preconcats the

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值