自定义View_Paint的详细讲解

自定义View_Paint的详细讲解

声明:本文作为学习总结,感谢扔物线的相关文章的帮助。
在View中显示颜色,Canvas主要通过三种途径实现的:drawColor/RGB/ARGB()、drawBitmap()和图形文字实现,其中第一种是通过直接填写颜色值实现,第二种是显示图片的颜色(还原图片颜色),第三种是通过对画笔(Paint)的设置实现。
这里写图片描述

1、着色器的使用

对于Paint的颜色设置有两种方式:paint.setColor(int 颜色值)和Shader(着色器)实现。对于第一种可以根据实际颜色直接设置颜色值,实现对画笔颜色的改变。本章重点讲解的是对于着色器的使用,在 Android 的绘制里使用 Shader ,并不直接用 Shader 这个类,而是用它的几个子类。具体来讲有 LinearGradient 、RadialGradient 、SweepGradient、 BitmapShader 和ComposeShader。
1.1 LinearGradient 线性渐变
构造方法:
LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
参数:
x0 y0 x1 y1:渐变的两个端点的位置
color0 color1 是端点的颜色
tile:端点范围之外的着色规则,类型是 TileMode。TileMode 一共有 3 个值可选: CLAMP, MIRROR 和 REPEAT。CLAMP 延展模式,会在端点之外延续端点处的颜色;MIRROR 是镜像模式;REPEAT 是重复模式

示例代码:

 Shader shader1 = new LinearGradient(100, 100, 500, 500, Color.parseColor("#ff0000"),Color.parseColor("#0000ff"), Shader.TileMode.CLAMP);
  paint.setShader(shader);
 canvas.drawCircle(500,500,400,paint);

示例效果:
这里写图片描述
1.2 RadialGradient 辐射渐变
构造方法:
RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, TileMode tileMode)。

参数:
centerX centerY:辐射中心的坐标
radius:辐射半径
centerColor:辐射中心的颜色
edgeColor:辐射边缘的颜色
tileMode:辐射范围之外的着色模式。

示例代码:

Shader shader = new RadialGradient(500,500,500,Color.parseColor("#ff0000"),Color.parseColor("#0000ff"), Shader.TileMode.CLAMP);
paint.setShader(shader);
canvas.drawCircle(500,500,400,paint);

示例效果:
这里写图片描述
1.3 SweepGradient 扫描渐变
构造方法:
SweepGradient(float cx, float cy, int color0, int color1)

参数:
cx cy :扫描的中心
color0:扫描的起始颜色
color1:扫描的终止颜色

示例代码:

Shader shader = new SweepGradient(500,500,Color.parseColor("#ff0000"),Color.parseColor("#0000ff");
paint.setShader(shader);
canvas.drawCircle(500,500,400,paint);

示例效果:
这里写图片描述
1.4 BitmapShader 图片着色器
构造方法:
BitmapShader(Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)

参数:
bitmap:用来做模板的 Bitmap 对象
tileX:横向的 TileMode
tileY:纵向的 TileMode

示例代码:

Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.ss);
Shader shader = new BitmapShader(bitmap1,Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
paint.setShader(shader);
canvas.drawCircle(500,500,400,paint);

示例效果:
这里写图片描述
1.5 ComposeShader 混合着色器
上面介绍的是针对于单一的着色器处理,谷歌其实还提供了将两种着色器混合起来处理的效果,一般都是对于两个BitmapShader的叠加处理。
构造方法:
ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode)

参数:
shaderA, shaderB:两个相继使用的 Shader
mode: 两个 Shader 的叠加模式,即 shaderA 和 shaderB 应该怎样共同绘制。它的类型是 PorterDuff.Mode 。
其中PorterDuff.Mode是用来指定两个图像共同绘制时的颜色策略的。它是一个 enum,不同的 Mode 可以指定不同的策略。一共有17种,大致分为两类:Alpha 合成 (Alpha Compositing)和混合 (Blending)。

示例代码:

Shader shader = new BitmapShader(bitmap1,Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
Shader shader3 = new BitmapShader(bitmap,Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
Shader shader2 = new ComposeShader(shader,shader3, PorterDuff.Mode.MULTIPLY);
paint.setShader(shader2);
canvas.drawCircle(500,500,400,paint);

示例效果:
这里写图片描述

1.5.1 Alpha 合成
借助谷歌官方文档,理解一下。
这里写图片描述
Alpha 合成:
这里写图片描述
1.5.2 混合 (Blending)
这里写图片描述

2、颜色过滤

除了通过着色器来更改显示效果外,还可通过颜色过滤器来使用,在 Paint 里设置 ColorFilter ,使用的是 Paint.setColorFilter(ColorFilter filter) 方法。 ColorFilter 并不直接使用,而是使用它的子类。它共有三个子类:LightingColorFilter PorterDuffColorFilter 和 ColorMatrixColorFilter。
2.1 灯光照射 LightingColorFilter
构造方法:LightingColorFilter(int mul, int add)

参数:
参数中是包含ARGB值,其中mul 是数值相乘,add是将数值相加。

R' = R * mul.R / 0xff + add.R  
G' = G * mul.G / 0xff + add.G  
B' = B * mul.B / 0xff + add.B 

示例代码:

Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.ss);
ColorFilter lightingColorFilter = new LightingColorFilter(0xff0000, 0x000000);
paint2.setColorFilter(lightingColorFilter);
canvas.drawBitmap(bitmap1,0,0,paint2);

示例图片:
这里写图片描述
另外还有PorterDuffColorFilter和ColorMatrixColorFilter使用基本相同。

3、setXfermode

“Xfermode” 其实就是 “Transfer mode”,用 “X” 来代替 “Trans” 是一些美国人喜欢用的简写方式。严谨地讲, Xfermode 指的是你要绘制的内容和 Canvas 的目标位置的内容应该怎样结合计算出最终的颜色。但通俗地说,其实就是要你以绘制的内容作为源图像,以 View 中已有的内容作为目标图像,选取一个 PorterDuff.Mode 作为绘制内容的颜色处理方案。
但是图片周围可能包括透明层,在绘制时除了包含图片本身,四周的透明层会变为黑色,需要通过离屏缓冲来处理,该处理方式包括两种方式:Canvas.saveLayer()和View.setLayerType(),还有最直接的方式是UI截图时不包含多余的透明层处理的方式。

猜你喜欢

转载自blog.csdn.net/xk7298/article/details/79365903