关于ondraw你该知道的(二)
目录
1.变形矩阵Matrix
0)简介
原理:也是一个矩阵,矩阵运算类似于ColorMatrix,区别是Matrix是一个3×3的矩阵,对图形的变化也是通过在初始矩阵的基础上修改矩阵元素值,从而达到修改图像的目的。
1)主要函数
通过Matrix可以图像进行平移,旋转,缩放,错切等操作。
旋转:Matrix.setRotate()
平移:Matrix.setTranslate()
缩放:Matrix.setScale()
错切:Matrix.setSkew()
这些方法操作的都是像素点,比如缩放为原来的0.5,效果就是将每个像素点的X坐标变成原来的0.5倍。
2)示例
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(true);
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.draw_img);
Matrix matrix = new Matrix();
canvas.drawBitmap(mBitmap, matrix, paint);
//平移
matrix.setTranslate(0, 150);
canvas.drawBitmap(mBitmap, matrix, paint);
}
可以看到原图,将平移后的效果绘制
3)set()、post()、pre()函数
set:重置矩阵中所有值,只保存set修改图像的操作
post:将修改图像的操作插入到一系列操作的队尾
pre:将修改图像的操作插入到一系列操作的队首
举个例子:
Matrix m = new Matrix();
m.preScale(0,0); //①
m.postScale(2, 2); //②
m.preTranslate(1, 1); // ③
执行顺序为:③-①-②
2.drawbitmapmesh像素块分析
图中横竖交叉的线,将图形分成N块,我们可以通过改变横竖线的交叉点坐标,从而达到改变像素块的效果。
看看主要函数,如下:
drawBitmapMesh(Bitmap bitmap,
int meshWidth,
int meshHeight,
float[] verts,
int vertOffset,
int[] colors,
int colorOffset,
Paint paint)
meshWidth:需要的横向网格数目
meshHeight:需要的纵向网格数目
verts:网格交叉点的坐标数组
vertOffset:数组中跳过的坐标对(x,y)的数目
主要看看verts:它的元素组成形式是(x1,y1,x2,y2,x3,y3.....),所以数组长度为偶数。
可以参考一些效果,实现图形的扭曲,变化等。
https://blog.csdn.net/qq_38261174/article/details/80042258
https://www.jianshu.com/p/51d8dd99d27d
2.Shader渲染器
可以用来实现一系列的渐变、渲染效果。
1)图像渲染———BitmapShader
效果:最终paint画的形状,就是渲染出来的图形
代码:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap bitmap =BitmapFactory.decodeResource(getResources(),R.mipmap.draw_img);
int radius = bitmap.getHeight()/2;
//画笔
Paint paint = new Paint();
paint.setAntiAlias(true);
//BitmapShader设置给paint
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);
paint.setShader(bitmapShader);
//画圆
canvas.drawCircle(radius, radius, radius, paint);
}
说下函数BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY)的参数:
bitmap:渲染的图形
tileX:表示在位图上X方向渲染器平铺模式(TileMode)
tileY:表示在位图上Y方向渲染器平铺模式(TileMode),与tileX同理
再看看TileMode的分类效果:
REPEAT :重复(效果为横向或纵向不断重复显示bitmap )
MIRROR :镜像(效果为横向或纵向不断翻转重复 )
CLAMP:拉伸(效果为横向或纵向拉伸图片在该方向的最后一个像素,区分电脑屏保的拉伸)
2)LinearGradient——–线性渲染
重点:需要指定渐变的起始颜色
效果:
代码:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int radius = 100;
//画笔
Paint paint = new Paint();
paint.setAntiAlias(true);
//Shader设置给paint
paint.setShader(new LinearGradient(0,0,radius/2,radius/2,Color.RED,Color.BLUE,Shader.TileMode.REPEAT));
//画圆
canvas.drawCircle(radius, radius, radius, paint);
}
看看LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, TileMode tile)参数:
x0:是梯度线起始点的x坐标
y0:是梯度线起始点的y坐标
x1:是梯度线末端的x坐标
y1:是梯度线末端的y坐标
color0:渐变线开始的颜色。
color1:渐变线末端的颜色。
tile:平铺着色器的平铺模式
3)RadialGradient——–环形渲染
效果:
代码:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//1.圆心X坐标2.Y坐标3.半径 4.颜色数组 5.相对位置数组,可为null 6.渲染器平铺模式
RadialGradient mRadialGradient = new RadialGradient(240, 240, 200, new int[] {
Color.YELLOW, Color.BLUE, Color.TRANSPARENT, Color.RED }, null,
Shader.TileMode.REPEAT);
Paint mPaint = new Paint();
// 绘制环形渐变
mPaint.setShader(mRadialGradient);
// 第一个,第二个参数表示圆心坐标
// 第三个参数表示半径
canvas.drawCircle(500, 500, 400, mPaint);//画一个容器,大的圆
}
构造方法:
public RadialGradient(float x, float y, float radius, int[] colors, float[] positions,Shader.TileMode tile)
float x: 圆心X坐标
float y: 圆心Y坐标
float radius: 半径
int[] colors: 渲染颜色数组
floate[] positions: 相对位置数组,可为null, 若为null,可为null,颜色沿渐变线均匀分布
Shader.TileMode tile:渲染器平铺模式
public RadialGradient(float x, float y, float radius, int color0, int color1,Shader.TileMode tile)
float x: 圆心X坐标
float y: 圆心Y坐标
float radius: 半径
int color0: 圆心颜色
int color1: 圆边缘颜色
Shader.TileMode tile:渲染器平铺模式
4)SweepGradient——–扫描渲染
效果:
代码:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//1.中心X坐标 2.中心Y坐标 3.半径 4.颜色数组 5.相对位置数组,可为null 6.渲染器平铺模式
SweepGradient mRadialGradient = new SweepGradient(240, 360, new int[]
{Color.CYAN,Color.DKGRAY,Color.GRAY,Color.LTGRAY,Color.MAGENTA,
Color.GREEN,Color.TRANSPARENT, Color.BLUE }, null);
Paint mPaint = new Paint();
mPaint.setShader(mRadialGradient);
canvas.drawCircle(240, 360, 100, mPaint);
}
5)ComposeShader——组合渲染
用法参考:https://blog.csdn.net/IO_Field/article/details/78460519
omposeShader的作用是实现两个颜色渐变效果的叠加,如BitmapShader与LinearGradient的混合渲染效果等,叠加的效果由过渡模式(Xfermode)或者PorterDuff.Mode来决定。
它有两个构造函数:
- ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode)
- ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode)
参数解释:
- shaderA:渲染效果
- shaderB:渲染效果
- mode:叠加的效果模式。对于过渡模式(Xfermode)或者PorterDuff.Mode
模式参考:https://blog.csdn.net/io_field/article/details/78222527
3.PathEffect
1)简介
含义就是用各种笔触去绘制路径。
分类有:
1.CornerPathEffect:用平滑的方式衔接Path的各部分
2.DashPathEffect :将Path的线段虚线化
3.PathDashPathEffect:与DashPathEffect效果类似但需要自定义路径虚线的样式
4.DiscretePathEffect:离散路径效果
5.ComposePathEffect :两种样式的组合。先使用第一种效果然后在此基础上应用第二种效果
6.SumPathEffect: 两种样式的叠加。先将两种路径效果叠加起来再作用于Path
2)示例
效果:
代码:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画笔
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.GREEN);
mPaint.setStrokeWidth(8);
//平滑
Path path = new Path();
path.moveTo(10, 100);
for (int i = 1; i <= 30; i++) {
path.lineTo(30 * i,(float)(Math.random()*100+100));
}
mPaint.setPathEffect(new CornerPathEffect(30));//拐角圆角的度数
canvas.drawPath(path,mPaint);
//虚线
canvas.translate(0,300);
//参数
//1.数组float[ ] { }中第一个数表示每条实线的长度,第二个数表示每条虚线的长度
//2.构造方法的第二个参数:phase表示偏移量,动态改变该值会使路径产生动画效果
mPaint.setPathEffect(new DashPathEffect(new float[]{10,10},2));
canvas.drawPath(path,mPaint);
}