Android中提供了Shader类专门用来渲染图像以及一些几何图形,Shader下面包括几个直接子类,分别是BitmapShader、ComposeShader、LinearGradient、RadialGradient、SweepGradient。
- BitmapShader主要用来渲染图像
- BitmapShader shader=new BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY)
- bitmap 在渲染器内使用的位图
- tileX The tiling mode for x to draw the bitmap in. 在位图上X方向平铺模式
- tileY The tiling mode for y to draw the bitmap in. 在位图上Y方向平铺模式
- TileMode:平铺方式(一共有三种)
- CLAMP :如果渲染器超出原始边界范围,会复制范围内边缘染色。
- REPEAT :横向和纵向的重复渲染器图片,平铺。
- MIRROR :横向和纵向的重复渲染器图片,这个和REPEAT重复方式不一样,他是以镜像方式平铺。
- BitmapShader shader=new BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY)
- LinearGradient 用来进行梯度渲染
- LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, TileMode tile)
- LinearGradient shader = new LinearGradient(0, 0, endX, endY, new int[]{startColor, midleColor, endColor},new float[]{0 , 0.5f,1.0f}, TileMode.MIRROR);
- 参数一为渐变起初点坐标x位置,参数二为y轴位置,参数三和四分辨对应渐变终点
- 其中参数new int[]{startColor, midleColor,endColor}是参与渐变效果的颜色集合,
- 其中参数new float[]{0 , 0.5f, 1.0f}是定义每个颜色处于的渐变相对位置, 这个参数可以为null,如果为null表示所有的颜色按顺序均匀的分布
- 第五个 平铺方式
- RadialGradient 用来进行环形渲染,实现某一区域内颜色的环形渐变效果
- RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, TileMode tileMode)
- RadialGradient shader = new RadialGradient (float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile)
- x:环形的圆心x坐标
- y:环形的圆心y坐标
- radius:环形的半径
- colors:环形渐变的颜色数组
- positions:指定颜色数组的相对位置
- tile:平铺方式
- SweepGradient 用来进行梯度渲染,扫描渲染,就是以某个点位中心旋转一周所形成的效果!
- SweepGradient(float cx, float cy, int color0, int color1)
- SweepGradient shader = new SweepGradient (float cx, float cy, int[] colors, float[] positions)
- cx:扫描的中心x坐标
- cy:扫描的中心y坐标
- colors:梯度渐变的颜色数组
- positions:指定颜色数组的相对位置
- ComposeShader则是一个 混合渲染,渲染效果的叠加
- ComposeShadershader = new ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
- shaderA:第一种渲染效果
- shaderB:第二种渲染效果
- mode:两种渲染效果的叠加模式
- ComposeShadershader = new ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
可以和其它几个子类组合起来使用。
BitmapShader
先来说说Shader.TileMode的三种模式:CLAMP、MIRROR和REPETA。
- CLAMP:就是如果渲染器超出原始边界范围,则会复制边缘颜色对超出范围的区域进行着色
- MIRROR:则是在横向和纵向上以镜像的方式重复渲染位图。
- REPEAT:则是平铺形式重复渲染
下面用例子来看:
原图:
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
// 获取屏幕尺寸数据
screenSize = MeasureUtil.getScreenSize((Activity) context);
mRectF=new RectF();
mRectF.left = 0;
mRectF.right = screenSize[0];
mRectF.top = 0;
mRectF.bottom = screenSize[1];
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a);
bitmapShader = new BitmapShader(bitmap, TileMode.CLAMP,
TileMode.CLAMP);
mPaint.setShader(bitmapShader);
canvas.drawRect(mRectF, mPaint);
效果如图,图片右边和下边 超出图片范围 的都 复制了边缘的颜色:
再来试一下MIRROR:
bitmapShader = new BitmapShader(bitmap, TileMode.MIRROR,
TileMode.MIRROR);
效果如图,超出图片都是镜像:
接着是REPEAT,没什么好说的,就是重复:
看了这三张图,大家应该能理解TileMode的三种模式了。
这个类有两点要注意:
BitmapShader默认是从屏幕的左上角开始绘图的。
我们来做一个测试,将绘图的区域也就是mRectF做一下调整:
mRectF.left = 100;
mRectF.right = screenSize[0]-100;
mRectF.top = 100;
mRectF.bottom = screenSize[1]-100;
bitmapShader = new BitmapShader(bitmap, TileMode.CLAMP,
TileMode.CLAMP);
左右上下各减100,效果呢?山顶被砍头了….
如果我绘制的图形不从屏幕左上角开始绘制,怎么办?
BitmapShader提供了两个方法:setLocalMatrix(Matrix matrix)和getLocalMatrix(Matrix matrix)。
bitmapShader = new BitmapShader(bitmap, TileMode.CLAMP,TileMode.CLAMP);
// 实例一个矩阵对象
Matrix matrix = new Matrix();
// 设置矩阵变换
matrix.setTranslate(100, 300);
// 设置Shader的变换矩阵
bitmapShader.setLocalMatrix(matrix);
果然,绘制的起始点就从(0,0)变成了(100, 300):
LinearGradient
这个比较简单,直接看效果吧:
- 两种颜色CLAMP:
linearGradient=new LinearGradient(0, 0, 200, 200, Color.RED, Color.GREEN,TileMode.CLAMP);
mPaint.setShader(linearGradient);
canvas.drawRect(0, 0, 400, 400, mPaint);
- 两种颜色MIRROR:
linearGradient=new LinearGradient(0, 0, 200, 200, Color.RED, Color.GREEN, TileMode.MIRROR);
- 两种颜色REPEAT
linearGradient=new LinearGradient(0, 0, 200, 200, Color.RED, Color.GREEN, TileMode.REPEAT);
- 多种颜色 均匀分布
linearGradient=new LinearGradient(0, 0, 400, 400, new int[]{Color.RED,Color.GREEN,Color.BLUE}, null, TileMode.CLAMP);
- 多种颜色 个性分布
linearGradient=new LinearGradient(0, 0, 400, 400, new int[]{Color.RED,Color.GREEN,Color.BLUE}, new float[]{0f,0.9f,1.0f}, TileMode.CLAMP);
RadialGradient
根LinearGradient差不多。
radialGradient=new RadialGradient(200, 200, 200, Color.RED, Color.GREEN, TileMode.CLAMP);
radialGradient=new RadialGradient(200, 200, 200, Color.RED, Color.GREEN, TileMode.MIRROR);
radialGradient=new RadialGradient(200, 200, 200, Color.RED, Color.GREEN, TileMode.REPEAT);
radialGradient=new RadialGradient(200, 200, 200, new int[]{Color.RED,Color.GREEN,Color.BLUE}, null, TileMode.CLAMP);
radialGradient=new RadialGradient(200, 200, 200, new int[]{Color.RED,Color.GREEN,Color.BLUE}, new float[]{0f,0.1f,1.0f}, TileMode.CLAMP);
SweepGradient
直接上代码:
- 两种颜色
sweepGradient = new SweepGradient(400, 400, Color.RED, Color.YELLOW);
- 多种颜色 均匀分布
sweepGradient = new SweepGradient(400, 400, new int[] { Color.RED,
Color.GREEN, Color.BLUE }, null);
- 多种颜色 个性分布
sweepGradient = new SweepGradient(400, 400, new int[] { Color.RED,
Color.GREEN, Color.BLUE, Color.YELLOW }, new float[] { 0,
0.3f, 0.7f, 1.0f });
ComposeShader
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a);
mBitmapShader = new BitmapShader(bitmap,Shader.TileMode.REPEAT,Shader.TileMode.MIRROR);
mLinearGradient = new LinearGradient(0, 0, bitmap.getWidth(), bitmap.getHeight(),
new int[]{Color.RED,Color.GREEN,Color.BLUE,Color.WHITE},
null,Shader.TileMode.REPEAT);
mComposeShader = new ComposeShader(mBitmapShader,mLinearGradient,PorterDuff.Mode.DARKEN);
// 获取屏幕尺寸数据
int[] screenSize = MeasureUtil.getScreenSize((Activity) context);
mRectF=new RectF();
mRectF.left = 0;
mRectF.right = screenSize[0];
mRectF.top = 0;
mRectF.bottom = screenSize[1];
mPaint.setShader(mComposeShader);
canvas.drawRect(mRectF, mPaint);
效果图:
引用:
自定义控件其实很简单1/3 - AigeStudio - 博客频道 - CSDN.NET
Android学习笔记进阶15之Shader渲染 - 爱生活,爱编程 - 博客园
关于 android的 渲染器 Shader - 我爱洗澡 皮肤好好, 哦哦哦哦哦哦~ - 博客频道 - CSDN.NET
Android画图Path的使用 - tt_mc - 博客园
android Shader类简介_渲染图像示例 - 低级写手 我自由了 - ITeye技术网站