Android中Matrix的相关变换

Android中Matrix的相关变换

  我们在重写onDraw()方法时,经常会对绘制内容进行一些变换,这个时候,我们很有可能会用到Matrix。

  记得在之前我们讲ColorMatrixColorFilter时提到过ColorMatrix,当时我们说ColorMatrix实际上是对像素信息进行运算的规则,有了ColorMatrixColorFilter,就不用对海量的像素信息一个一个进行setColor()了,在这里Matrix和ColorMatrix类似,它实际就是对Canvas变化规则的封装。我们如果想对Canvas进行变换,那我们就需要借助Matrix了。

  如果想对Matrix进行比较规则的变换,我们常用的有这样几种操作:

  • translate
  • scale
  • rotate
  • skew

  translate、 scale和rotate都比较好理解,我就不赘述了,咱们就直接说说skew吧~顾名思义,skew就是像让Canvas倾斜一个角度,倾斜后就变成了一个斜的平行四边形。Matrix的skew操作有三类方法,分别是public boolean postSkew (float kx, float ky, float px, float py)public void setSkew (float kx, float ky, float px, float py)public boolean preSkew (float kx, float ky, float px, float py)(还有三个px和py为空的方法省略不说)。px和py很好理解,就是让画布歪斜的中心点。这么说可能不够精确,那就直接看看转换公式吧:x’ = x + kx*(x - px), y’ = y + ky*(y - py)

  到现在为止,对Matrix进行skew操作你应该掌握了,但你可能会有疑问,为什么像translate, scale, rotate 和 skew都是对应着set,pre, post三类方法?这其实就是对应着线性代数里的三种情况:

  • m.setXXX(m’) –> result = m’
  • m.postXXX(m’) –> result = m’ * m
  • m.preXXX(m’) –> result = m * m’

  通常我们使用m.setXXX(m’)和m.postXXX(m’)多一些。至于原因,m.setXXX(m’)好理解,m.postXXX(m’)是因为通常我们都是将之前想多canvas进行的变换封装到m中,接下来如果需要对canvas进行操作,那自然是对m继续变换了,而线性代数中的 m’ * m,实际的“物理含义”就是对m进行m’变换。

  除了以上操作我们会用的比较多以外,还有两个方法我们也会经常使用到:

  • public boolean setPolyToPoly (float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)
  • public boolean setRectToRect (RectF src, RectF dst, Matrix.ScaleToFit stf)

  在说setPolyToPoly()之前,先来看看Stack Overflow上的一张图吧~

这里写图片描述

  通过这张图你就可以明白setPolyToPoly()实际就是利用一些标志点来进行转换的,通过对比相应标志点位置的变化,来推算出matrix应该做何种变换。这样一来,它的几个参数是什么意思就很好理解,src和dst实际上就是封装着标志点的坐标,pointCount就是标志点的个数,srcIndex标识src的第srcIndex个位置开始是第一个点的坐标,dstIndex亦然。

  setRectToRect (RectF src, RectF dst, Matrix.ScaleToFit stf)和setPolyToPoly()很类似,只不过setRectToRect()是通过Rect来标识matrix的变化,src描述matrix变化前,dst描述matrix变化后,而Matrix.ScaleToFit是四种填充样式:

  • START:src填充dst的左边或者上边
  • CENTER:src居中填充dst的横向或者纵向
  • END:src填充dst的右边或者上边
  • FILL:src填充整个dst

  好勒~这就是Matrix常见的相关用法,不过,既然说到了这里,我们顺便说说Canvas的drawBitmapMesh (Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)。有了我们前面的基础,理解这个方法简直易如反掌。

  drawBitmapMesh()和setPolyToPoly()非常类似,他们都是用标记点来标识画布的变化。我们传入meshWidth和meshHeight两个参数,canvas会自动将bitmap按照这两个参数分成很多个网格,网格的每个顶点就是我们所说的标记点,他们现在描述的是bitmap变化之前的matrix,而verts描述的是bitmap变化之后的matrix,这样,我们就得到了和setPolyToPoly()类似的效果了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值