欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于ondraw你该知道的(二)

程序员文章站 2022-05-24 21:19:51
...

目录

1.变形矩阵Matrix

0)简介

1)主要函数

2)示例

3)set()、post()、pre()函数

2.drawbitmapmesh像素块分析

2.Shader渲染器

1)图像渲染———BitmapShader

2)LinearGradient——–线性渲染

3)RadialGradient——–环形渲染

4)SweepGradient——–扫描渲染

5)ComposeShader——组合渲染

3.PathEffect

1)简介

2)示例


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);
    }

关于ondraw你该知道的(二)

可以看到原图,将平移后的效果绘制

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块,我们可以通过改变横竖线的交叉点坐标,从而达到改变像素块的效果。

关于ondraw你该知道的(二)

看看主要函数,如下:

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画的形状,就是渲染出来的图形

关于ondraw你该知道的(二)

代码:

@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——–线性渲染

重点:需要指定渐变的起始颜色

效果:

关于ondraw你该知道的(二)

代码:

    @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——–环形渲染

效果:

关于ondraw你该知道的(二)

代码:

 @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——–扫描渲染

效果:

关于ondraw你该知道的(二)

代码:

  @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)示例

效果:

关于ondraw你该知道的(二)

代码:

 @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);
    }