Android Shader着色器/渲染器

android 进阶 专栏收录该内容
58 篇文章 1 订阅
一、介绍
Shader是绘图过程中的着色器,它有五个子类:
  1. BitmapShader:         位图渲染
  2. LinearGradient:        线性渲染
  3. SweepGradient:        梯度渲染
  4. RadialGradient:        光束渲染
  5. ComposeShader:     组合渲染
渲染模式:Shader.TileMode
  • Shader.TileMode.CLAMP:    边缘拉伸模式,它会拉伸边缘的一个像素来填充其他区域。
  • Shader.TileMode.MIRROR:    镜像模式,通过镜像变化来填充其他区域。需要注意的是,镜像模式先进行y轴方向的镜像操作,然后在进行x轴方向上的镜像操作。
  • Shader.TileMode.REPEAT:重复模式,通过复制来填充其他区域

下面的图:X轴是边缘拉伸模式,Y重复模式


镜像模式:xy轴均是镜像模式


二、效果介绍:

1.BitmapShader:         位图渲染

    构造方法:BitmapShader (Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)

    参数:

        bitmap:要处理的bitmap对象

        tileX:在X轴处理的效果,Shader.TileMode里有三种模式:CLAMP、MIRROR和REPETA

        tileY:在Y轴处理的效果,Shader.TileMode里有三种模式:CLAMP、MIRROR和REPETA

我们给画笔填充一个五角星,然后绘制一条直线

Shader shader[] = new Shader[8];
bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.star);
shader[0] = new BitmapShader(bitmap,Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(32);
paint.setShader(shader[0]);

int lineHeight = 100,lineOffset = 50;

canvas.drawLine(0,lineHeight,parentWidth,100,paint);

2.LinearGradient:        线性渲染

    LinearGradient是颜色线性渐变的着色器。

    构造函数:

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

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

    参数:

        (x0,y0)表示渐变的起点,(x1,y1)表示渐变的终点坐标,这两点都是相对于屏幕坐标系。

        color0,color1分别表示起点的颜色和终点的颜色。

        也传入多个颜色,和每个颜色的起始位置。

        colors[]传入多个颜色值进去

        positions[] 位置数组

        而且当positions参数传入null时,代表颜色是均匀的填充整个渐变区域的,显得比较柔和。

通过两个构造函数分别画两条线:

lineHeight += lineOffset;
shader[1] = new LinearGradient(0,lineHeight,parentWidth,lineHeight,Color.RED,Color.GREEN,Shader.TileMode.REPEAT);
paint.setShader(shader[1]);
canvas.drawLine(0,lineHeight,parentWidth,lineHeight,paint);

lineHeight += lineOffset;
shader[2] = new LinearGradient(0,lineHeight,parentWidth,lineHeight,GRADIENT_COLORS,null,Shader.TileMode.REPEAT);
paint.setShader(shader[2]);
canvas.drawLine(0,lineHeight,parentWidth,lineHeight,paint);

3.SweepGradient:        梯度渲染

        SweepGradient是梯度渐变,也称为扫描式渐变,可以实现雷达扫描效果。

        构造函数:

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

        参数:

            (cx,cy)表示渐变效果的中心点,也就是雷达扫描的圆点。color0和color1表示渐变的起点色和终点色。

            颜色渐变是顺时针的,从中心点的x轴正方形开始。

            注意:这里构造函数并不需要TileMode,因为梯度渐变的边界相当于无限大的。

        构造函数:

            SweepGradient(float cx, float cy,int colors[], float positions[])

        参数:

            colors[]颜色数组

            positions数组,该数组中每一个position对应colors数组中每个颜色在360度中的相对位置,

            position取值范围为[0,1],0和1都表示3点钟位置,0.25表示6点钟位置,0.5表示9点钟位置,0.75表示12点钟位置,

通过要个构造函数绘制两个实心圆,其中第二个圆指定positions

public static final int[] GRADIENT_COLORS = new int[]{
        Color.RED,Color.YELLOW,Color.BLUE, Color.GREEN, Color.WHITE, Color.RED };
public static final float[] GRADIENT_POSITONS = new float[]{
        0.0f,0.5f,0.55f,0.6f,0.65f,1.0f};

lineHeight += lineOffset +32;
shader[3] = new SweepGradient(150,lineHeight,GRADIENT_COLORS,null);
paint.setShader(shader[3]);
canvas.drawCircle(150,lineHeight,50,paint);


shader[4] = new SweepGradient(450,lineHeight,GRADIENT_COLORS,GRADIENT_POSITONS);
paint.setShader(shader[4]);
canvas.drawCircle(450,lineHeight,50,paint);

4.RadialGradient:        光束渲染

        RadialGradient:创建从中心向四周发散的辐射渐变效果,

        构造函数:

      RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)

        参数:

        centerX  圆心的X坐标

        centerY  圆心的Y坐标

        radius   圆的半径

        centerColor  中心颜色

        edgeColor   边缘颜色

        构造函数:

            RadialGradient(float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode)

        参数:

            colors[]传入多个颜色值进去,这样就会用colors数组中指定的颜色值一起进行颜色线性插值。

            stops数组,该数组中每一个stop对应colors数组中每个颜色在半径中的相对位置,

            stop[]取值范围为[0,1],0表示圆心位置,1表示圆周位置。如果stops数组为null,那么Android会自动为colors设置等间距的位置。

private float period = 0;   //偏移量变化周期值

lineHeight += lineOffset + 150;
shader[5] = new RadialGradient(150,lineHeight,10,Color.GREEN,Color.RED,Shader.TileMode.MIRROR);
paint.setShader(shader[5]);
canvas.drawCircle(150,lineHeight,100,paint);

if ( period < 250 || period >= 650){
    period = 250;
}else {
    period += 5F;
}
shader[6] = new RadialGradient(period,lineHeight,30,GRADIENT_COLORS,null,Shader.TileMode.MIRROR);
paint.setShader(shader[6]);
canvas.drawCircle(450,lineHeight,100,paint);

这里多指定了一个period,设置为渐变的圆心x轴坐标,这样就可以实现滚动的小球



同样也可以设置绘制的圆心跟随滚动:将圆心Y轴坐标设置为period,实现小球从上往下掉的效果

canvas.drawCircle(450,period,100,paint);

5.ComposeShader:     组合渲染

        ComposeShader用来组合不同的Shader,可以将两个不同的Shader组合在一起

    构造函数:

        ComposeShader (Shader shaderA, Shader shaderB, Xfermode mode)

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

    参数:

        shaderA shaderB 两种渲染效果

        mode 叠加效果:PorterDuff图形混合模式介绍

将bitmapShader和RadialGradient模式复合

lineHeight += lineOffset + 350;
bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.head);
shader[0] = new BitmapShader(bitmap, Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);
shader[6] = new RadialGradient(150,lineHeight,550,Color.BLACK,Color.TRANSPARENT, Shader.TileMode.CLAMP);
//混合产生新的Shader.
shader[7] = new ComposeShader(shader[0],shader[6],PorterDuff.Mode.DST_IN);
paint.setShader(shader[7]);
//以新的Shader绘制一个圆。
canvas.drawCircle(150,lineHeight,550,paint);

左下角的渐渐模糊的图片便是组合效果

全部代码:

//shader 画笔填充
private void my_shader(Canvas canvas){

    //Shader.TileMode是指平铺模式
    //Shader.TileMode.CLAMP是边缘拉伸模式,它会拉伸边缘的一个像素来填充其他区域。
    //Shader.TileMode.MIRROR是镜像模式,通过镜像变化来填充其他区域。需要注意的是,镜像模式先进行y轴方向的镜像操作,然后在进行x轴方向上的镜像操作。
    //Shader.TileMode.REPEAT是重复模式,通过复制来填充其他区域

    //bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.head);
    Shader shader[] = new Shader[8];
    bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.star);
    shader[0] = new BitmapShader(bitmap,Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);
    Paint paint = new Paint();
    paint.setStyle(Paint.Style.FILL);
    paint.setStrokeWidth(32);
    paint.setShader(shader[0]);

    int lineHeight = 100,lineOffset = 50;

    canvas.drawLine(0,lineHeight,parentWidth,100,paint);
    //canvas.drawCircle(240,240,100,paint);

    //LinearGradient是颜色线性渐变的着色器。
    //LinearGradient (float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
    //(x0,y0)表示渐变的起点,(x1,y1)表示渐变的终点坐标,这两点都是相对于屏幕坐标系。color0,color1分别表示起点的颜色和终点的颜色。
    //LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile)
    //多色渐变的构造函数中,我们可以传入多个颜色,和每个颜色的占比。而且当positions参数传入null时,代表颜色是均匀的填充整个渐变区域的,显得比较柔和。
    lineHeight += lineOffset;
    shader[1] = new LinearGradient(0,lineHeight,parentWidth,lineHeight,Color.RED,Color.GREEN,Shader.TileMode.REPEAT);
    paint.setShader(shader[1]);
    canvas.drawLine(0,lineHeight,parentWidth,lineHeight,paint);

    lineHeight += lineOffset;
    shader[2] = new LinearGradient(0,lineHeight,parentWidth,lineHeight,GRADIENT_COLORS,null,Shader.TileMode.REPEAT);
    paint.setShader(shader[2]);
    canvas.drawLine(0,lineHeight,parentWidth,lineHeight,paint);

    //SweepGradient是梯度渐变,也称为扫描式渐变,效果有点类似与雷达扫描效果。
    //SweepGradient(float cx, float cy, int color0, int color1)
    // (cx,cy)表示渐变效果的中心点,也就是雷达扫描的圆点。color0和color1表示渐变的起点色和终点色。
    // 颜色渐变是顺时针的,从中心点的x轴正方形开始。
    // 注意:这里构造函数并不需要TileMode,因为梯度渐变的边界相当于无限大的。
    //SweepGradient(float cx, float cy,int colors[], float positions[])
    //colors[]颜色数组
    //positions数组,该数组中每一个position对应colors数组中每个颜色在360度中的相对位置,
    // position取值范围为[0,1],0和1都表示3点钟位置,0.25表示6点钟位置,0.5表示9点钟位置,0.75表示12点钟位置,
    lineHeight += lineOffset +32;
    shader[3] = new SweepGradient(150,lineHeight,GRADIENT_COLORS,null);
    paint.setShader(shader[3]);
    canvas.drawCircle(150,lineHeight,50,paint);


    shader[4] = new SweepGradient(450,lineHeight,GRADIENT_COLORS,GRADIENT_POSITONS);
    paint.setShader(shader[4]);
    canvas.drawCircle(450,lineHeight,50,paint);

    //RadialGradient:创建从中心向四周发散的辐射渐变效果,其有两个构造函数:
    //RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)
    //centerX  圆心的X坐标
    //centerY  圆心的Y坐标
    //radius   圆的半径
    //centerColor  中心颜色
    //edgeColor   边缘颜色
    //RadialGradient(float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode)
    //colors[]传入多个颜色值进去,这样就会用colors数组中指定的颜色值一起进行颜色线性插值。
    // stops数组,该数组中每一个stop对应colors数组中每个颜色在半径中的相对位置,
    // stop[]取值范围为[0,1],0表示圆心位置,1表示圆周位置。如果stops数组为null,那么Android会自动为colors设置等间距的位置。
    lineHeight += lineOffset + 150;
    shader[5] = new RadialGradient(150,lineHeight,10,Color.GREEN,Color.RED,Shader.TileMode.MIRROR);
    paint.setShader(shader[5]);
    canvas.drawCircle(150,lineHeight,100,paint);

    if ( period < 250 || period >= 650){
        period = 250;
    }else {
        period += 5F;
    }
    shader[6] = new RadialGradient(period,lineHeight,30,GRADIENT_COLORS,null,Shader.TileMode.MIRROR);
    paint.setShader(shader[6]);
    canvas.drawCircle(450,period,100,paint);


    //ComposeShader用来组合不同的Shader,可以将两个不同的Shader组合在一起,它有两个构造函数:
    //ComposeShader (Shader shaderA, Shader shaderB, Xfermode mode)
    //ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
    lineHeight += lineOffset + 350;
    bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.head);
    shader[0] = new BitmapShader(bitmap, Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);
    shader[6] = new RadialGradient(150,lineHeight,550,Color.BLACK,Color.TRANSPARENT, Shader.TileMode.CLAMP);
    //混合产生新的Shader.
    shader[7] = new ComposeShader(shader[0],shader[6],PorterDuff.Mode.DST_IN);
    paint.setShader(shader[7]);
    //以新的Shader绘制一个圆。
    canvas.drawCircle(150,lineHeight,550,paint);
}

  • 0
    点赞
  • 0
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
内容简介 《Android开发权威指南》内容上涵盖了用最新的Android版本开发的大部分场景。全书分4个部分,分别从Android基础介绍、环境搭建、SDK介绍,到应用剖析、组件介绍、综合实例演示,以及符合潮流的、最新的移动开发技术,如HTML5、OpenGL ES、NDK编程、Android测试驱动开发等几个方面讲述。从技术实现上,讲解了6大完整综合案例及源代码分析,分别是新浪微博客户端、蓝牙聊天、全键盘输入法、月球登陆(游戏)、贪吃蛇(游戏)、笑脸连连看(游戏)。 《Android开发权威指南》注重对实际动手能力的指导,在遵循技术研发知识体系严密性的同时,在容易产生错误、不易理解的环节上配备了翔实的开发情景截图;并将重要的知识点和开发技巧以“多学一招”、“扩展学习”、“技巧点拨”等的活泼形式呈现给读者。在程序实例的讲解方面,主要将实例安插在Android开发的精髓知识章节,这为读者学习与实践结合提供了很好的指导。 《Android开发权威指南》配套光盘包含开发视频及全部源程序,指导读者快速、无障碍地学通Android实战开发技术。 《Android开发权威指南》适合具备一定软件开发经验、想快速进入Android开发领域的程序员,具备一些手机开发经验的开发者和Android开发爱好者学习使用;也适合作为相关培训学校的Android培训教材。 图书目录 第一部分 准备篇 第1章 初识庐山真面目——Android开发简介 2 1.1 Android的基本概念 2 1.1.1 Android简介 2 1.1.2 Android的版本 4 1.1.3 Android的系统构架 5 1.1.4 Android的应用程序框架 6 1.2 JIL Widget介绍 7 1.3 小结 8 第2章 工欲善其事,必先利其器——搭建和使用Android开发环境 9 2.1 开发包及工具的安装 9 2.1.1 开发Android程序都需要些什么 9 2.1.2 安装JDK和配置Java开发环境 10 2.1.3 Eclipse的安装与汉化 11 2.1.4 安装AndroidSDK 12 2.1.5 安装Eclipse插件ADT 13 2.2 真实体验——编写第一个Android程序(随机绘制圆饼) 15 2.2.1 创建Android工程 15 2.2.2 在模拟器中运行Android程序 17 2.2.3 界面控件的布局 19 2.2.4 编写代码 20 2.2.5 调试程序 23 2.2.6 在手机上运行和调试程序 28 2.3 迁移Android工程可能发生的错误 29 2.4 不需要写一行代码的开发工具:AppInventor 31 2.4.1 AppInventor简介 31 2.4.2 AppIntentor的下载和安装 31 2.4.3 用拖曳控件的方式设计界面 33 2.4.4 像拼图一样拼装代码 34 2.5 小结 37 第二部分 基础篇 第3章 千里之行始于足下——Android程序设计基础 40 3.1 Android应用程序框架 40 3.1.1 Android项目的目录结构 40 3.1.2 AndroidManifest.xml文件的结构 42 3.2 Android应用程序中的资源 44 3.3 Android的应用程序组件 44 3.3.1 Activity(Android的窗体) 45 3.3.2 Service(服务) 45 3.3.3 Broadcast Receiver(广播接收器) 45 3.3.4 Content Provider(内容提供者) 46 3.4 Android程序的UI设计 46 3.4.1 手工配置XML布局文件 46 3.4.2 ADT自带的可视化UI设计器 47 3.4.3 使用DroidDraw设计UI布局 47 3.5 小结 48 第4章 我的UI我做主——用户界面开发基础 49 4.1 Activity的使用方法 49 4.1.1 创建Activity 49 4.1.2 配置Activity 50 4.1.3 显示其他的Activity(Intent与Activity) 52 4.2 Activity的生命周期 55 4.3 在不同Activity之间传递数据 60 4.3.1 使用Intent传递数据 60 4.3.2 使用静态变量传递数据 62 4.3.3 使用剪切板传递数据 63 4.3.4 使用全局对象传递数据 65 4.3.5 返回数据到前一个Activity 67 4.4 视图(View) 68 4.4.1 视图简介 68 4.4.2 使用XML布局文件定义视图 69 4.4.3 在代码中控制视图 70 4.5 布局(Layout) 72 4.5.1 框架布局
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值