之前一段时间,我都在研究Android自定义View的相关知识,随着逐渐的深入,渐渐了解到了一些Android图像处理的知识,主要是Bitmap,Canvas,Shader,Matric,ColorFilterXfermode的使用。所以准备写一系列文章介绍一下这些方面的知识。

图像处理相关概念介绍

 要想了解Shader的概念,首先要了解Android图像处理中几个比较重要的概念:bitmap,canvas,drawing primitive,paint。需要注意的是,上述四个词并不指android中的类,而是四个概念。
 bitmap指画布。画家画图时都需要一块画布,然后才会在画布上绘制各种形状和颜色,Android中的Bitmap就有画布的功能。比如下面这段代码。

    static Bitmap makeSrc(int w,int h) {            Bitmap bm = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);            Canvas c = new Canvas(bm);            Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);                p.setColor(0xFF66AAFF);            c.drawRect(100,100,100,100,p);            return bm;}

 Bitmap这里就充当一个画布的作用,之后Canvas的操作都是在这个Bitmap画布进行绘制。
 canvas是绘制操作的集合,你可以把它理解成画家的手,通过它你可以在画布上绘制各种图像和颜色。相应的在Android的Canvas类中就封装了绘制相关的各种操作,比如drawXXX系列。
 drawing primitive指绘制实体或者原始内容,比如画家绘画时可能会画一个苹果,也可能只是绘制一些线段,矩形等。这些都是绘制实体。在Android中,Path,Rect,Text,Bitmap都可以充当drawing primitive的角色,因为你都可以把它们绘制到画布上。你也可以这样理解,Canvas中的drawXXX系列函数中的XXX都是指drawing primitive。
 paint就是指画家的神奇画笔啦。Android中的Paint类就充当这个角色,我们可以通过Paint来配置画笔的颜色,粗细,纹理等。我们系列文章主要讲解的Shader,ColorFilter,Xfermode三个类都和Paint直接相关。

Shader概念介绍

 Shader,也就是所谓的着色器。它应用于计算机图形学领域,指一组提供计算机图像资源在执行绘制任务时使用的指令,用于计算图像的颜色和明暗。从技术角度来看,着色器是渲染器的一部分,它负责计算目标的颜色。以我的理解,Paint就是渲染器,Paint.setShader这个函数展示了着色器和渲染器之间的关系。下面这段代码显示了Shader的使用方式。

    String text = "Shader";    Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.photo);    BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);    Paint paint = new Paint();    paint.setShader(bitmapShader);    paint.setTextSize(100);    paint.setStrokeWidth(50);    canvas.drawText(text,0,text.length(),150,400,paint);

 上边的代码片段使用了BitmapShader,也就是说使用图片上相应位置的颜色进行着色。就相当于使用这个图片作为背景,字体颜色是透明色,字体在(150,400)位置进行绘制,字体最终显示的颜色就是图片中相应位置的颜色。
Shader.TileMode是指平铺模式,一共有三种类型:CLAMP,MIRROR,REPEAT。构造函数中后两个参数分别规定了当绘制实体的x或y轴范围超过一定范围时(比如BitmapShaderBitmap的大小,LinearGradient中构造函数传入的x,y值),着色器填充的行为。我们以BitmapShader为例,来讲述三种模式的区别。原图如下所示,来自于这个博客。

    Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.img);    BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.XXX, Shader.TileMode.XXXX);    Paint paint = new Paint();    paint.setShader(bitmapShader);    canvas.drawColor(Color.GRAY);    canvas.drawRect(0,0,800,800,paint);

Shader.TileMode.CLAMP是边缘拉伸模式,它会拉伸边缘的一个像素来填充其他区域。效果图如下所示,我们可以看到,超出bitmap大小的范围都被图片边缘的颜色所填充。

Shader.TileMode.MIRROR是镜像模式,也就是说它通过镜像变化来填充其他区域。需要注意的是,TileMode是先处理y轴方向的操作,然后在进行x轴方向的操作。也就是说先进行y轴方向的镜像操作,然后在进行x轴方向上的镜像操作。不过我觉得好像先进行哪个方向上的操作并没有什么区别,最终效果是一样的。其效果图如下所示:

Shader.TileMode.REPEAT是重复模式,通过复制来填充其他区域

 你也可以对x,y轴使用不同的TileMode,可以得到不同的效果。

Shader类型介绍

BitmapShader的用法很简单,上边的实例中也有用到,所以我们就不再详细介绍它了。

LinearGradient

LinearGradient是颜色线性渐变的着色器。它有两个构造函数:
 双色渐变的构造函数是

public LinearGradient (float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)

 参数中,(x0,y0)表示渐变的起点,(x1,y1)表示渐变的终点坐标,这两点都是相对于屏幕坐标系。color0,color1分别表示起点的颜色和终点的颜色。不同于BitmapShader需要x,y轴两个平铺模式参数,LinearGradient只需要一个TileMode,表示从(x0,y0)到(x1,y1)方向上的平铺模式
LinearGradient的平铺效果可能比较难以理解,需要大家多做几次实验才能明白。
 下图是200200的由红色到黄色的线性渐变效果着色器绘制200200的矩形的效果图,着色器的TileModeMIRROR:

 下图是上述的着色器绘制400*400的效果图,我们可以看到二者的区别,在屏幕坐标轴的(200,200)方向(第二张图中的黑色线段所代表的方向)上颜色是先从红色到黄色,超过(200,200)这个点之后,由于设置平铺模式为MIRROR所以颜色就又从黄色逐渐变成了红色。这个对角线外上的点的颜色是和其在对角线上(-200,200)方向上的投影点的颜色相同,也就是第二张图中蓝色直线上点的颜色都是相同的。

 多色渐变的构造函数是

public LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)

 多色渐变的构造函数中,我们可以传入多个颜色,和每个颜色的占比。而且当positions参数传入null时,代表颜色是均匀的填充整个渐变区域的,显得比较柔和。

SweepGradient

SweepGradient是梯度渐变,也称为扫描式渐变,效果有点类似与雷达扫描效果。它也有两个构造方法,分别为两色渐变和多色渐变,二者的区别和之前介绍的LinearGradient的构造函数类似,我们这里就只介绍双色渐变的构造函数:

public SweepGradient(float cx, float cy, int color0, int color1)

 在构造函数的参数中,(cx,cy)表示渐变效果的中心点,也就是雷达扫描的圆点。color0和color1表示渐变的起点色和终点色。颜色渐变是顺时针的,从中心点的x轴正方形开始。需要注意的是,这里构造函数并不需要TileMode,因为梯度渐变的边界相当于无限大的。

RadialGradient

RadialGradient是径向渐变,径向渐变就是从圆的中心点向四周渐变的特效,你可以把它想象成一个圆,从圆点到圆周沿着半径有颜色的渐变效果。它也有两个构造函数,我们只介绍双色渐变的构造函数。

`public RadialGradient(float centerX, float centerY, float radius,

        int centerColor, int edgeColor, TileMode tileMode)`

 在构造函数的参数中,(centerX,centerY)表示径向渐变中的圆点,radius表示圆的半径长度,centerColor表示圆点颜色,edgeColor表示圆周颜色,titleMode表示平铺模式,它的作用方向是沿着半径方向。下图就是一个有红色到黄色的径向渐变,平铺模式为CLAMP,所以超出圆周的范围的点的颜色就都是圆周的颜色黄色。

ComposeShader

ComposeShader用来组合不同的Shader,可以将两个不同的Shader组合在一起,它有两个构造函数:

ComposeShader (Shader shaderA, Shader shaderB, Xfermode mode)  ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode mode)  

 二者的区别就是一个使用PorterDuff的模式,另一个可以使用所有的Xfermode。这两个混合模式我们在之后的文章中将会详细讲到。

后记

 这里只是简单介绍了一下Shader的概念和基本用法,之后会多加一些实际使用的情况,希望大家持续关注。

更多相关文章

  1. view的clickable属性和点击background颜色改变
  2. Android修改原生RatingBar颜色、大小,以及自定义的样式
  3. android设置edittext光标的颜色
  4. Android资源文件 - 使用资源存储字符串 颜色 尺寸 整型 布尔值
  5. Android 颜色渲染(五) LinearGradient线性渲染
  6. android4.0系统点击后颜色-浅蓝色
  7. Android根据属性值自定义改变图片颜色
  8. Android MenuItem 设置文字颜色-TextColor的设置
  9. Android hex RGB 各种颜色值 colors.xml

随机推荐

  1. Android(安卓)Studio 快捷键中英文对译
  2. android 获取手机的各种状态
  3. Android中如何获取应用版本号
  4. 分享一个Android左右侧滑的效果实现 slid
  5. Android级联菜单的实现方法
  6. 对Android中Tab的使用总结
  7. Mac安装Homebrew
  8. Sublime Text3解决There are no packages
  9. 利用 JavaScript 构建命令行应用
  10. 详解uni-app中的样式