Android 中 Canvas 绘图之 Shader 使用图文详解

563 查看

概述

我们在用Android中的Canvas绘制各种图形时,可以通过Paint.setShader(shader)方法为画笔Paint设置shader,这样就可以绘制出多彩的图形。那么Shader是什么呢?做过GPU绘图的同学应该都知道这个词汇,Shader就是着色器的意思。我们可以这样理解,Canvas中的各种drawXXX方法定义了图形的形状,画笔中的Shader则定义了图形的着色、外观,二者结合到一起就决定了最终Canvas绘制的被色彩填充的图形的样子。

android.graphics.Shader有五个子类,分别是:BitmapShader、LinearGradient、RadialGradient、SweepGradient和ComposeShader,下面依次对这几个类的使用分别说明。


BitmapShader

BitmapShader,顾名思义,就是用Bitmap对绘制的图形进行渲染着色,其实就是用图片对图形进行贴图。

BitmapShader构造函数如下所示:

第一个参数是Bitmap对象,该Bitmap决定了用什么图片对绘制的图形进行贴图。

第二个参数和第三个参数都是Shader.TileMode类型的枚举值,有以下三个取值:CLAMP 、REPEAT 和 MIRROR。

  • CLAMP
    CLAMP表示,当所画图形的尺寸大于Bitmap的尺寸的时候,会用Bitmap四边的颜色填充剩余空间。我们有一个Bitmap,如下所示:

20160112194103941

注意,我们这张图片的四个角是有一定的圆弧的,也就是该Bitmap的四个角点处的像素都是透明的。
我们使用该Bitmap,演示TileMode为CLAMP的效果,代码如下所示:

效果如下所示:

20160113194246690

我们可以看到,由于我们所绘制的矩形矩形区域比Bitmap大,Bitmap就用右侧边和下侧边的最外层的颜色填充了矩形区域。由于原Bitmap右下角的像素是透明的,所以绘制的矩形的右下角就用透明填充了。

如果我们绘制的图形尺寸小于Bitmap尺寸,那么效果看起来就像是对原Bitmap裁剪了一下而已,如下所示:

20160113194351598

我们可以看到,当我们所绘制的圆形尺寸小于Bitmap尺寸的时候,看起来的效果就是我们用所绘制的圆形对Bitmap进行了裁剪。

  • REPEAT
    REPEAT表示,当我们绘制的图形尺寸大于Bitmap尺寸时,会用Bitmap重复平铺整个绘制的区域。
    示例代码如下所示:

效果如下所示:

20160113194514414

  • MIRROR
    与REPEAT类似,当绘制的图形尺寸大于Bitmap尺寸时,MIRROR也会用Bitmap重复平铺整个绘图区域,与REPEAT不同的是,两个相邻的Bitmap互为镜像。
    代码如下所示:

效果如下所示:

20160113194551388

最后需要说的是,在构造BitmapShader时,tileX和tileY可以取不同的值,二者不用非得一致。


LinearGradient

我们可以用LinearGradient创建线性渐变效果,其有两个构造函数:

我们重点说一下第一个构造函数,在此基础上理解第二个构造函数就很简单了。

LinearGradient是用来创建线性渐变效果的,它是沿着某条直线的方向渐变的,坐标(x0,y0)就是这条渐变直线的起点,坐标(x1,y1)就是这条渐变直线的终点。需要说明的是,坐标(x0,y0)和坐标(x1,y1)都是Canvas绘图坐标系中的坐标。color0和color1分别表示了渐变的起始颜色和终止颜色。与BitmapShader类似,LinearGradient也支持TileMode,有以下三个取值:CLAMP 、REPEAT 和 MIRROR。

使用代码如下所示:

效果如下所示:

20160113194621046

上面我们使用了CLAMP,但是由于我们绘制的矩形与渐变位置的大小一样大,所以CLAMP效果不明显。

我们把绘制的区域变大,还是用CLAMP,这次绘制整个Canvas大小的矩形。