在上一篇文章中我们分析了自定义View的流程,这片文章我们来分析一下绘制过程中的 Paint 类的API
Paint API
我们只看一些常用的API
1. setColor 设置画笔的颜色
void setColor(@ColorInt int color)
2. setARGB 设置画笔的ARGB值
/**
* a,r,g,b的取值范围都是0~255
*/
void setARGB(int a, int r, int g, int b)
3. setAlpha 设置画笔的透明度,0为透明
/**
* a的取值范围都是0~255
*/
void setAlpha(int a)
4. setAntiAlias 设置是否抗锯齿
void setAntiAlias(boolean aa)
5. setDither 设置是否防抖动,设置true会图像更加平滑饱满,图像更清晰
void setDither(boolean dither)
6. setStyle 设置画笔的样式
void setStyle(Style style)
以下为画笔的样式,我们以使用宽为b的画笔绘制一个半径为r的园为例。
- Paint.Style.FILL 绘制一个半径为r的圆
- Paint.Style.STROKE 绘制一个内径为(r-b/2)宽为b的圆环
- Paint.Style.FILL_AND_STROKE 绘制一个半径为(r+b/2)的圆
7. setStrokeWidth 设置画笔的宽
void setStrokeWidth(float width)
8. setStrokeJoin 设置折线处的样式
void setStrokeJoin(Join join)
9.setStrokeCap 设置线帽
void setStrokeCap(Cap cap)
10.setFilterBitmap 设置双线性过滤 true时提高图片的过渡效果
void setFilterBitmap(boolean filter)
11. setXfermode 设置图层混合模式
上图是16中混合模式,还有两种不常用的。接下来我们一一介绍。图中的黄色的圆为dst(先绘制的)目标图,蓝色的矩形是src(后绘制的)源图。所有的模式都是作用在src上面的。
PorterDuff.mode.CLEAR 清除src源图及相交部分
PorterDuff.mode.SRC 显示src源图
PorterDuff.mode.DST 显示dst目标图
PorterDuff.mode.SRC_OVER dst、src都显示src在上层
PorterDuff.mode.DST_OVER dst、src都显示dst在上层
PorterDuff.mode.SRC_IN src在上层显示并清除src的非交集部分
PorterDuff.mode.DST_IN src在下层显示并清除src的非交集部分
PorterDuff.mode.SRC_OUT 显示src的非交集部分,交集部分透明
PorterDuff.mode.DST_OUT 清除src的非交集部分,交集部分透明
PorterDuff.mode.SRC_ATOP 取src的交集部分和dst的非交集部分
PorterDuff.mode.DST_ATOP 取dst的交集部分和src的非交集部分
PorterDuff.mode.XOR 交集部分变透明
PorterDuff.mode.DARKEN 交集部分颜色加深
PorterDuff.mode.LIGHTEN 交集部分颜色变亮
PorterDuff.mode.MULTIPLY 取交集部分颜色叠加
PorterDuff.mode.SCREEN 交集部分滤色
PorterDuff.mode.ADD 交集部分饱和度相加
PorterDuff.mode.OVER 交集部分叠加
12. setShader 设置着色器
Shader setShader(Shader shader)
我们分析一下系统提供的Shader的子类
- LinearGradient 线性渐变
LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[],
@Nullable float positions[], @NonNull TileMode tile)
x0,y0 表示开始点的位置
x1,y1表示结束点的位置
colors[] 颜色的数组
positions[] 指定各开始的颜色的位置取值范围 0~1,为null时颜色均匀分布
TileMode 表示重复模式 (CLAMP 重复最后一个像素点、REPEAT 整个重复、MIRROR 镜像重复)
LinearGradient(float x0, float y0, float x1, float y1,@ColorInt int color0,
@ColorInt int color1,@NonNull TileMode tile)
该构造函数只能指定两个颜色
构造函数中两个点的连线方向决定了颜色的渐变方向。
paint.setShader(new LinearGradient(0,0,500,0,new int[]{Color.RED,Color.YELLOW},
new float[]{0,1}, Shader.TileMode.REPEAT));
canvas.drawRect(0,0,1000,1000,paint);
- SweepGradient 扫描式渐变
SweepGradient(float cx, float cy,
@NonNull @ColorInt int colors[], @Nullable float positions[])
cx,cy 表示圆心
colors 表示渐变颜色的数组
positions 各颜色开始的位置0~1
SweepGradient(float cx, float cy, @ColorInt int color0, @ColorInt int color1)
设置两个颜色的构造函数
paint.setShader(new SweepGradient(500,500,new int[]{Color.RED,Color.YELLOW},new float[]{0,1}));
canvas.drawRect(0,0,1000,1000,paint);
- RadialGradient 径向渐变
RadialGradient(float centerX, float centerY, float radius,@NonNull @ColorInt int colors[],
@Nullable float stops[],@NonNull TileMode tileMode)
centerX,centerY 指定一个圆心
radius 指定半径
colors 指定颜色的数组
stops 指定每个颜色的结束位置
TileMode 重复模式
RadialGradient(float centerX, float centerY, float radius,
@ColorInt int centerColor, @ColorInt int edgeColor, @NonNull TileMode tileMode)
指定两个颜色的构造函数
paint.setShader(new RadialGradient(500, 500, 300, new int[]{Color.RED, Color.YELLOW}, new float[]{0, 1}, Shader.TileMode.REPEAT));
canvas.drawRect(0, 0, 1000, 1000, paint);
- BitmapGradient 位图着色器
BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY)
bitmap 指定一个位图
tileX X方向的重复模式
tileY Y方向的重复模式
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap);
//X、Y方向都重复
paint.setShader(new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
canvas.drawRect(0, 0, 1000, 1000, paint);
- ComposeShader 混合着色器
ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode)
ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull PorterDuff.Mode mode)
shaderA 着色器,混合模式中的dst
shaderB 着色器,混合模式中的src
Xfermode、PorterDuff.Mode 混合模式。Xfermode是一个基类使用时我们使用其子类PorterDuffXfermode。
LinearGradient linearGradient = new LinearGradient(0, 0, 500, 0, new int[]{Color.RED, Color.YELLOW}, new float[]{0, 1}, Shader.TileMode.REPEAT);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap);
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
paint.setShader(new ComposeShader(linearGradient,bitmapShader,new PorterDuffXfermode(PorterDuff.Mode.ADD)));
canvas.drawRect(0, 0, 1000, 1000, paint);
13. setColorFilter()设置滤镜效果
ColorFilter setColorFilter(ColorFilter filter)
- LightingColorFilter
//LightingColorFilter 滤镜
//LightingColorFilter(@ColorInt int mul, @ColorInt int add)
//mul和add都是和颜色值格式相同的int。mul用来和目标颜色值相乘,add是用来和目标颜色值相加
//R' = R*mul.R/0xff + add.R
//G' = G*mul.G/0xff + add.G
//B' = B*mul.B/0Xff + add.B
//mull 为0xffffff add为0x000000 时显示的是原图效果
//要降低某颜色值的效果时修改mul的值,增加修改add对应的值
LightingColorFilter lightingColorFilter = new LightingColorFilter(0xffffff, 0x000000);
- PorterDuffColorFilter
//PorterDuffColorFilter 滤镜
//PorterDuffColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode)
//相当于先创建一个颜色为color的图层,然后使用mode进行图层混合
PorterDuffColorFilter duffColorFilter = new PorterDuffColorFilter(0xffff0000, PorterDuff.Mode.DARKEN);
- ColorMatrixColorFilter
//ColorMatrixColorFilter(@NonNull float[] array) 使用一个矩阵数组的构造函数
//ColorMatrixColorFilter 颜色矩阵
//使用一个20位的float数组来表示颜色矩阵
//[
// a,b,c,d,e,
// f,g,h,i,j,
// k,l,m,n,o,
// p,q,r,s,t
// ]
//使用颜色矩阵的计算方式为
// R' = R*a+G*b+B*c+A*d+e;
// G' = R*f+G*g+B*h+A*i+j;
// B' = R*k+G*l+B*m+A*n+o;
// A' = R*p+G*q+B*r+A*s+t;
//设置下面的颜色矩阵原图不变
//float[] floats = {
// 1, 0, 0, 0, 0,
// 0, 1, 0, 0, 0,
// 0, 0, 1, 0, 0,
// 0, 0, 0, 1, 0
//}
float[] floats = {
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0
};
ColorMatrixColorFilter colorFilter = new ColorMatrixColorFilter(floats);
//ColorMatrixColorFilter(@NonNull ColorMatrix matrix) 使用ColorMatrix的构造函数
ColorMatrix cm = new ColorMatrix();
//修改颜色矩阵,该方法也是操作的颜色矩阵的数组
//r,g,b,a修改是数组中对应的a[0],g[6],m[12],s[18]
cm.setScale(1,1,1,1);
//设置饱和度
//0 为灰色,1 为原色, >1增加饱和度
cm.setSaturation(0);
//通过旋转颜色的坐标系来改变颜色矩阵
//0 表示旋转red 1 表示旋转green 2表示旋转blue
cm.setRotate(0,100);
ColorMatrixColorFilter colorFilter = new ColorMatrixColorFilter(cm);
常见的滤镜效果
// 黑白
public static final float colormatrix_heibai[] = {
0.8f, 1.6f, 0.2f, 0, -163.9f,
0.8f, 1.6f, 0.2f, 0, -163.9f,
0.8f, 1.6f, 0.2f, 0, -163.9f,
0, 0, 0, 1.0f, 0};
// 复古
public static final float colormatrix_fugu[] = {
0.9f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.8f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f, 0.0f,
0, 0, 0, 1.0f, 0};
// 哥特
public static final float colormatrix_gete[] = {
1.9f, -0.3f, -0.2f, 0, -87.0f,
-0.2f, 1.7f, -0.1f, 0, -87.0f,
-0.1f, -0.6f, 2.0f, 0, -87.0f,
0, 0, 0, 1.0f, 0};
// 传统
public static final float colormatrix_chuan_tong[] = {
1.0f, 0.0f, 0.0f, 0, -10f,
0.0f, 1.0f, 0.0f, 0, -10f,
0.0f, 0.0f, 1.0f, 0, -10f,
0, 0, 0, 1, 0};
// 淡雅
public static final float colormatrix_danya[] = {
0.6f, 0.3f, 0.1f, 0, 73.3f,
0.2f, 0.7f, 0.1f, 0, 73.3f,
0.2f, 0.3f, 0.4f, 0, 73.3f,
0, 0, 0, 1.0f, 0};
// 光晕
public static final float colormatrix_guangyun[] = {
0.9f, 0, 0, 0, 64.9f,
0, 0.9f, 0, 0, 64.9f,
0, 0, 0.9f, 0, 64.9f,
0, 0, 0, 1.0f, 0};
// 胶片
public static final float colormatrix_fanse[] = {
-1.0f, 0.0f, 0.0f, 0.0f, 255.0f,
0.0f, -1.0f, 0.0f, 0.0f, 255.0f,
0.0f, 0.0f, -1.0f, 0.0f, 255.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
// 褐片
public static final float colormatrix_hepian[] = {
1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.8f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.8f, 0.0f, 0.0f,
0, 0, 0, 1.0f, 0};
// 怀旧
public static final float colormatrix_huajiu[] = {
0.2f, 0.5f, 0.1f, 0, 40.8f,
0.2f, 0.5f, 0.1f, 0, 40.8f,
0.2f, 0.5f, 0.1f, 0, 40.8f,
0, 0, 0, 1, 0};
// 胶片2
public static final float colormatrix_jiao_pian[] = {
0.71f, 0.2f, 0.0f, 0.0f, 60.0f,
0.0f, 0.94f, 0.0f, 0.0f, 60.0f,
0.0f, 0.0f, 0.62f, 0.0f, 60.0f,
0, 0, 0, 1.0f, 0};
// 蓝调
public static final float colormatrix_landiao[] = {
2.1f, -1.4f, 0.6f, 0.0f, -71.0f,
-0.3f, 2.0f, -0.3f, 0.0f, -71.0f,
-1.1f, -0.2f, 2.6f, 0.0f, -71.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
// 浪漫
public static final float colormatrix_langman[] = {
0.9f, 0, 0, 0, 63.0f,
0, 0.9f, 0, 0, 63.0f,
0, 0, 0.9f, 0, 63.0f,
0, 0, 0, 1.0f, 0};
// 锐色
public static final float colormatrix_ruise[] = {
4.8f, -1.0f, -0.1f, 0, -388.4f,
-0.5f, 4.4f, -0.1f, 0, -388.4f,
-0.5f, -1.0f, 5.2f, 0, -388.4f,
0, 0, 0, 1.0f, 0};
// 梦幻
public static final float colormatrix_menghuan[] = {
0.8f, 0.3f, 0.1f, 0.0f, 46.5f,
0.1f, 0.9f, 0.0f, 0.0f, 46.5f,
0.1f, 0.3f, 0.7f, 0.0f, 46.5f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
// 清宁
public static final float colormatrix_qingning[] = {
0.9f, 0, 0, 0, 0,
0, 1.1f, 0, 0, 0,
0, 0, 0.9f, 0, 0,
0, 0, 0, 1.0f, 0};
// 夜色
public static final float colormatrix_yese[] = {
1.0f, 0.0f, 0.0f, 0.0f, -66.6f,
0.0f, 1.1f, 0.0f, 0.0f, -66.6f,
0.0f, 0.0f, 1.0f, 0.0f, -66.6f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
// 酒红
public static final float colormatrix_jiuhong[] = {
1.2f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.9f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.8f, 0.0f, 0.0f,
0, 0, 0, 1.0f, 0};
// 湖光掠影
public static final float colormatrix_huguang[] = {
0.8f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.9f, 0.0f, 0.0f,
0, 0, 0, 1.0f, 0};
// 泛黄
public static final float colormatrix_huan_huang[] = {
1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f, 0.0f,
0, 0, 0, 1.0f, 0};
14.setMaskFilter 这是边缘效果,是用该方法前要关闭硬件加速setLayerType(LAYER_TYPE_SOFTWARE,null);
MaskFilter setMaskFilter(MaskFilter maskfilter)
- BlurMaskFilter 对图层的边缘进行模糊处理
//radius 模糊半径
//blur 模糊处理的模式
//NORMAL 向目标内外模糊radius宽的地方,内外延伸的延伸均取自目标的边缘颜色
//INNER 向目标内部延伸radius宽,取目标边缘外的颜色
//OUTER 向目标外部延伸radius宽,取目标边缘的颜色,显示目标
//SOLID 向目标外部延伸radius宽,取目标的颜色,不显示目标
BlurMaskFilter(float radius, Blur style)
使用上面的模式在黑色的矩形内绘制一个图片
- EmbossMaskFilter 实现浮雕效果
//direction 表示光源的位置
//ambient 环境光照强度 0~1
//specular 反射等级 值越小越亮
//blurRadius 照亮前的模糊量,就是光照中亮边的宽度
EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)
15. setTextSize 设置字体的大小
void setTextSize(float textSize)
16.setTextScaleX 设置字体的缩放比例
void setTextScaleX(float scaleX)
17. setTextAlign 设置文本的对齐方式
void setTextAlign(Align align)
18. setUnderlineText 添加下划线
void setUnderlineText(boolean underlineText)
19. setStrikeThruText 添加删除线
void setStrikeThruText(boolean strikeThruText)
20. getTextBounds 获取文本的Rect值,该方法会将测算好的left、top、right、bottom封装到Rect中
void getTextBounds(String text, int start, int end, Rect bounds)
getTextBounds(char[] text, int index, int count, Rect bounds)
21. getFontMetrics 获取字体度量的对象
FontMetrics getFontMetrics()
public static class FontMetrics {
/**
* The maximum distance above the baseline for the tallest glyph in
* the font at a given text size.
*/
public float top;
/**
* The recommended distance above the baseline for singled spaced text.
*/
public float ascent;
/**
* The recommended distance below the baseline for singled spaced text.
*/
public float descent;
/**
* The maximum distance below the baseline for the lowest glyph in
* the font at a given text size.
*/
public float bottom;
/**
* The recommended additional space to add between lines of text.
*/
public float leading;
}
22. measureText 获取文本的宽度
float measureText(char[] text, int index, int count)
float measureText(String text, int start, int end)
float measureText(String text)
float measureText(CharSequence text, int start, int end)
该文并没有将所有的API都罗列出来,剩下的API可查看官方文档Paint_API