Android——Shader渲染器

2024-05-13 06:48
文章标签 android shader 渲染器

本文主要是介绍Android——Shader渲染器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

本文参考自 ——http://www.cnblogs.com/tianzhijiexian/p/4298660.html
这里很多内容直接复制抄袭,算是转载吧,感谢原作者。

二、shader的子类

BitmapShader
LinearGradient
SweepGradient
RadialGradient
ComposeShader
怎么用,我们一个个试试。

三、BitmapShader

3.1 构造方法

顾名思义,将bitmap作为着色器,那么画笔画出来的就是该bitmap。
BitMap只有一个构造方法

BitmapShader (Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)
第一个参数:要处理的bitmap对象
第二个参数:在X轴处理的效果,Shader.TileMode里有三种模式:CLAMP、MIRROR和REPEAT
第三个参数:在Y轴处理的效果,Shader.TileMode里有三种模式:CLAMP、MIRROR和REPEAT

下面我们就来用代码进行各种模式的演示,演示之前自然要准备一个演示图片了:
这里写图片描述
洛奇英雄传,黛莉娅 2月3号就能玩了,好激动!

3.2 CLAMP模式

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);Bitmap delia = BitmapFactory.decodeResource(getResources(),R.drawable.delia);BitmapShader bitmapShader = new BitmapShader(delia, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);mPaint.setShader(bitmapShader);canvas.drawRect(getLeft(), getTop(), getRight(), getBottom(),mPaint);
}

这里写图片描述
可以看得出来,这是将分辨将右边和下边的一个像素进行拉伸后的效果。
所以可以将clamp看做是边缘拉伸模式

3.3 MIRROR模式

代码和上面一样,只是改了X轴的渲染模式。

BitmapShader bitmapShader = new BitmapShader(delia, Shader.TileMode.MIRROR, Shader.TileMode.CLAMP);

这里写图片描述
可以看到,mirror是翻转模式

3.4 REPEAT模式

代码和上面一样,只是改了X轴的渲染模式。

BitmapShader bitmapShader = new BitmapShader(delia, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);

这里写图片描述
顾名思义,REPEAT就是重复模式了。

3.5 扩展,绘制圆形头像。
@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);Bitmap delia = BitmapFactory.decodeResource(getResources(),R.drawable.delia);BitmapShader bitmapShader = new BitmapShader(delia, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);mPaint.setShader(bitmapShader);int width = getWidth();int height = getHeight();int radius = width < height? width/2 : height/2;int cx = getRight()/2 - getLeft()/2;int cy = getBottom()/2 - getTop()/2;canvas.drawCircle(cx, cy, radius, mPaint);
}

这里写图片描述
设置了shader之后的画笔可以看做一个特殊的笔刷,画出来的东西就是该笔刷的效果。无论你画什么形状,画出来的东西就是该笔刷图案。
这对于我来说有点难以描述,希望大家能知道我说的什么意思。

四、LinearGradient

这是一个线性渐变的着色器。有两个构造方法:

4.1 构造方法

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

(x0,y0) (x1,y1)分别是起点和终点坐标
color0和color1分别是初始颜色和渐变后颜色
TileMode也是只有三种,不再赘述


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

这个构造和上面一个类似, 第一个构造只能在两种颜色间渐变。
而这个构造可以进行多种颜色渐变
colors是颜色的数组
positions是位置的数组,存储的是渐变后的颜色百分比位置,和颜色对应。如下图,游标就是positions。


如图所示,两个构造之间的区别。
第一个构造:
这里写图片描述

第二个构造:
这里写图片描述

4.2 各种模式简单说明

clamp,终点颜色一致延伸。
repeat,在终点位置,重复。
mirror,在终点位置,翻转。
自己想象吧,clamp和mirror可能效果不错,但是repeat应该会很突兀。

4.3 构造方法2的演示

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);int top = getTop();int left = getLeft();int bottom = getBottom();int right = getRight();int[] colors = {Color.GREEN, Color.RED, Color.BLUE, Color.YELLOW};float[] positions = {0f, 0.3f, 0.6f, 1f};// positions可以为null,代表均匀填充渐变。LinearGradient linearGradient = new LinearGradient(left, top, right, top, colors, positions, Shader.TileMode.CLAMP);mPaint.setShader(linearGradient);canvas.drawRect(left, top, right, bottom, mPaint);
}

这里写图片描述

4.4 扩展,闪烁的TextView

此Demo在Android群英传中有,感谢徐宜生大神。

/*** Created by AItsuki on 2016/2/2.*/
public class FlashTextView extends TextView {private Matrix matrix;private LinearGradient linearGradient;private int width;private int dx;private int translate;public FlashTextView(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);linearGradient = new LinearGradient(0, 0,w,0,new int[]{Color.RED,Color.YELLOW,Color.RED,Color.RED},null, Shader.TileMode.CLAMP);TextPaint paint = getPaint();paint.setShader(linearGradient);matrix = new Matrix();width = w;dx = width / 125 > 0 ? width/60 : 1; //60帧,两秒内}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);translate += dx;// |red---|---yellow---|---red---|---red|// 平移宽度的六分之五后,所有黄色已经看不见if(translate > width/6*5) {
//            translate = -width/2; //向左平移宽度的一半后,所有黄色已经看不见// 为什么不用注释的,因为两次闪光有一点点间隔比较舒服。translate = -width/6*5;}matrix.setTranslate(translate, 0);linearGradient.setLocalMatrix(matrix);postInvalidateDelayed(16);}
}

这里写图片描述

五、SweepGradient

扫描/梯度渲染。

5.1 构造方法

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

5.2 效果展示

和线性渐变差不多,不做更多的演示和说明。

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);SweepGradient gradient =  new SweepGradient(200,200,new int[]{Color.RED,Color.YELLOW,Color.GREEN,Color.BLUE,Color.CYAN,Color.RED},null);mPaint.setShader(gradient);canvas.drawCircle(200,200,200,mPaint);
}

这里写图片描述

六、RadialGradient

径向渐变,径向渐变说的简单点就是个圆形中心向四周渐变的效果

6.1 构造方法

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

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

6.2 效果展示

也适合线性渐变一样,没什么特别的。

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);RadialGradient gradient = new RadialGradient(200,200,200,new int[]{Color.RED,Color.YELLOW,Color.GREEN,Color.BLUE,Color.CYAN},null, Shader.TileMode.CLAMP);mPaint.setShader(gradient);canvas.drawCircle(200,200,200,mPaint);
}

这里写图片描述

七、ComposeShader

组合渲染,可以将两个shader组合起来使用,需要设置混合模式。

7.1 构造方法

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

两个构造没有什么区别,PorterDuff是Xfermode 的子类。

###7.2 效果展示
比如这样,BitmapShader + LinearGradient

public ComposeDemo(Context context, AttributeSet attrs) {super(context, attrs);Bitmap delia = BitmapFactory.decodeResource(getResources(), R.drawable.delia);BitmapShader bitmapShader = new BitmapShader(delia, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);LinearGradient linearGradient = new LinearGradient(0,0,0,delia.getHeight(),Color.BLACK,Color.TRANSPARENT, Shader.TileMode.CLAMP);ComposeShader composeShader = new ComposeShader(bitmapShader, linearGradient, PorterDuff.Mode.DST_IN);mPaint = new Paint();mPaint.setShader(composeShader);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawRect(getLeft(),getTop(),getRight(),getBottom(),mPaint);}

这里写图片描述

##八、Shader和Matrix
shader可以通过setLocalMatrix设置图形矩阵,和Bitmap设置矩阵的方法一致。
本博文在介绍LinearGradient的时候已经演示过通过矩阵平移打造闪烁Textview的效果。
这里不再对Matrix进行介绍,有兴趣的话可以看原帖或者百度搜索,都有非常详细的教程。

这篇关于Android——Shader渲染器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/984972

相关文章

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR