关于ondraw你该知道的(二)

目录

1.变形矩阵Matrix

0)简介

1)主要函数

2)示例

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

2.drawbitmapmesh像素块分析

2.Shader渲染器

1)图像渲染———BitmapShader

2)LinearGradient——–线性渲染

3)RadialGradient——–环形渲染

扫描二维码关注公众号,回复: 6797505 查看本文章

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

https://img-blog.csdnimg.cn/20190306152840879.png

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

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

https://upload-images.jianshu.io/upload_images/1856419-29381107dcd149af.png?imageMogr2/auto-orient/

看看主要函数,如下:

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

https://img-blog.csdnimg.cn/20190306161427943.png

代码:

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

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

效果:

https://img-blog.csdnimg.cn/20190306162540959.png

代码:

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

效果:

https://img-blog.csdnimg.cn/20190306163654327.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MzIxMDk4,size_16,color_FFFFFF,t_70

代码:

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

效果:

https://img-blog.csdnimg.cn/20190306164250730.png

代码:

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

效果:

https://img-blog.csdnimg.cn/20190306170459320.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MzIxMDk4,size_16,color_FFFFFF,t_70

代码:

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

猜你喜欢

转载自blog.csdn.net/qq_37321098/article/details/88237159