美文网首页
canvas的使用

canvas的使用

作者: 名字_都被占了 | 来源:发表于2018-04-07 12:52 被阅读0次
    1:画圆
    canvas.drawCircle(width / 2, height / 2, radius, mPaint);//绘制圆形,第一个参数是圆心的x坐标,第二个参数是圆心的y坐标,第三个参数是半径,单位都是像素
    2:画矩形canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);//这里绘制出来的矩形是实心的矩形,而不是空心的矩形线条,因为paint设置的style是Paint.Style.FILL,前四个参数的具体含义请看下图
    image.png
    3:canvas.save()和canvas.restore()的区别
    @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
            canvas.drawRect(10,10,getMeasuredWidth()-10,getMeasuredHeight()-10,paint1);
            canvas.save();
            canvas.translate(10,0);
            canvas.restore();
            super.onDraw(canvas);
        }
    
    区别是:当调用save方法后,就将canvas的位置和角度记录下来了,然后接下来就可以进行画布的平移,旋转之类的位置变化操作,也可以进行画图操作,不过此时所画的图是在进行了位置变化操作之后的canvas上进行的,如果要还原上一次保存的canvas的位置的话,就调用restore方法,这时canvas的位置就回到了上一次save时的状态了。
    4,画圆弧:drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

    oval :指定圆弧的外轮廓矩形区域。
    startAngle: 圆弧起始角度(x轴的正右的方向,是0度的位置),单位为度。
    sweepAngle: 圆弧扫过的角度,顺时针方向为正角度,单位为度
    useCenter: 如果为True时,用来绘制扇形,如果为false时,用来绘制弧形。
    paint: 绘制圆弧的画板属性,如颜色,是否填充等。

    paint.setStyle(Paint.Style.FILL);
    canvas.drawArc(200,100,800,500,180,60,false,paint);
    
    以上两句代码画出的形状是
    5,画笔的一些方法

    1:用paint的时候有三种Style,分别是
    Paint.Style.STROKE 只绘制图形轮廓(描边)
    Paint.Style.FILL 只绘制图形内容 ,默认是Paint.Style.FILL
    Paint.Style.FILL_AND_STROKE 既绘制轮廓也绘制内容


    image.png

    2:mPaint.setStrokeWidth(40);//用来设置画笔的宽度

    6,设置画布的颜色,这类颜色填充方法一般用于在绘制之前设置底色,或者在绘制之后为界面设置半透明蒙版。
            canvas.drawColor(Color.RED);
            canvas.drawARGB(100,100,100,100);
            canvas.drawRGB(100,100,100);
    
    7,设置线条的宽度,在STROKE和FILL_AND_STROKE下使用
    paint.setStrokeWidth(10);//设置线条宽度为10像素
    
    8,在绘制的时候,往往需要开启抗锯齿来让图形和文字的边缘更加平滑
            paint=new Paint(Paint.ANTI_ALIAS_FLAG);//静态开启抗锯齿
            paint.setAntiAlias(true);//动态开启抗锯齿
    
    9,绘制一个点,前两个参数是x,y坐标,点的大小可以通过paint.setStrokeWidth来设置,点的形状可以通过paint.setStrokeCap来设置,其中,SQUARE或BUTT画出来是方形的点,ROUND画出来是圆形的点。
    canvas.drawPoint(100,100,paint);
    
    10,画椭圆
    canvas.drawOval(100,100,200,500,paint);
    
    11,画线,由于直线不是封闭图形,所以paint.setStyle对直线没有影响,canvas.drawLine是画一条线,可以用canvas.drawLines批量画线
    canvas.drawLine(200,200,400,400,paint);
    
    12,画圆角矩形,第五个和第六个参数是矩形的每个圆角的横向半径和纵向半径
    canvas.drawRoundRect(200,300,400,500,80,80,paint);
    
    13,根据path画图形
    canvas.drawPath(path, paint);
    

    其中,Path对象有如下

    第一组,add...方法(添加完整封闭图形,除了addPath())

            path.addCircle(300,300,200, Path.Direction.CW);//添加圆
            //path.addOval();//添加椭圆
            //path.addRect();//添加矩形
            //path.addRoundRect();添加圆角矩形
            //path.addPath();添加path
    

    第二组,...To方法(画直线或者曲线)

            //lineTo和rLineTo画直线
            paint.setStyle(Paint.Style.STROKE);//如果参数是Paint.Style.FILL,那么画出来的是个三角形,和上面的那个画圆弧的一样,将画笔style设置为FILL
            path.lineTo(100,100);//参数是绝对坐标,由当前位置(0,0)向(100,100)画一条直线
            path.rLineTo(100,0);//参数是相对坐标,由当前位置(100,100)向正右方100像素的位置画一条直线
            canvas.drawPath(path, paint);
    
            //moveTo移动原点位置
            paint.setStyle(Paint.Style.STROKE);
            path.lineTo(100,100);//相对于原点(0,0)画直线到点(100,100)
            path.moveTo(200,100);//此时原点坐标为(200,100)
            path.lineTo(200,0);//相对于原点(200,100)画直线到点(200,0),注意这个(200,0)点还是以(0,0)为原点的(200,0)点,因为用的是lineTo,如果是rLineTo()则原点为(200,100)
            canvas.drawPath(path, paint);
    
            //arcTo画弧线
            paint.setStyle(Paint.Style.STROKE);
            path.lineTo(100,100);
            path.arcTo(100,100,300,300,-90,90,false);//第七个参数为直线连线连到弧形起点,true为无痕迹,false为有痕迹,如果没有path.lineTo(100,100);这句
            //代码的话,true和false的效果是一样的
            canvas.drawPath(path, paint);
    
            //addArc画弧线
            paint.setStyle(Paint.Style.STROKE);
            path.lineTo(100,100);
            path.addArc(100,100,300,300,-90,90);//path.addArc(100,100,300,300,-90,90)相当于path.arcTo(100,100,300,300,-90,90,true),addArc()相当于arcTo()的第七个参数为true的简化版
            canvas.drawPath(path, paint);
    

    第三,Path的close方法,不是所有的子图形都需要使用path的close()来封闭的,当paint的style是FILL或者是FILL_AND_STROKE时,Path会自动封闭子图形,这就是上面画弧和画两条线,如果设置为FILL,画出来的是填充的弧和三角形的原因。

            paint.setStyle(Paint.Style.FILL);
            path.moveTo(100,100);
            path.lineTo(200,100);
            path.lineTo(150,150);
            canvas.drawPath(path, paint);//这里只绘制了两条边,但由于style是FILL,所以绘制时会自动封口
    

    第四,Path的setFillType方法,对于添加子图形类方法(如path.addCircle(),path.addRect())的方向,由方法的dir参数来控制,而对于画线类的方法(如path.lineTo(),path.arcTo())的方向就是图形的方向

            paint.setStyle(Paint.Style.FILL);
            path.addCircle(300,300,200, Path.Direction.CCW);//CW顺时针,CCW逆时针
            path.addCircle(300,300,100, Path.Direction.CW);
            path.setFillType(Path.FillType.INVERSE_WINDING);//EVEN_ODD是如果是奇数就绘制,也就是说如果两个图形有部分重合,那么重合的那部分就不绘制,绘制剩下的
            //WINDING是按方向进行相加的,顺时针方向+1,逆时针方向-1,最后为0的那部分不绘制,绘制剩下的
            //INVERSE_EVEN_ODD就是将EVEN_ODD反过来
            //INVERSE_WINDING就是将WINDING反过来
            canvas.drawPath(path,paint);
    
    来个图片,通俗易懂
    14,画Bitmap
    Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
    ...
    canvas.drawBitmap(bitmap,100,100,paint);
    
    15,绘制文字
            paint.setTextSize(100);//设置文字的大小
            canvas.drawText("你好啊",200,200,paint);
    

    以前记录过的

            Paint a=new Paint();
            a.setColor(Color.RED);
            //a.setAlpha(100);
            //a.setStyle(Style.FILL_AND_STROKE);//设置画笔的风格
            //a.setStrokeWidth(33);//设置空心线宽
            a.setTextSize(34);//设置画笔字体的大小
            //a.setTypeface(Typeface.DEFAULT_BOLD);//设置字体样式
            //a.setTextScaleX(55);//设置比例因子,以一为标准
            //a.setARGB(40, 45, 88, 66);//设置字体的颜色
            //a.setUnderlineText(true);//设置下划线
            //a.setTextSkewX(3);//设置倾斜因子,以零为标准
            canvas.drawColor(Color.GREEN);//设置背景颜色
            //canvas.drawText("n好啊", 70, 90, a);
            ///canvas.drawCircle(33, 22, 44, a);
            //canvas.drawLine(33, 44, 11, 22, a);
            //canvas.drawPoint(44, 55, a);
            //canvas.drawRoundRect(new RectF(55,277,488,499), 35, 22, a);//绘制圆角矩形
            //canvas.drawOval(new RectF(33,333,222,444), a);//绘制椭圆形
            //Path ab=new Path();
            //ab.moveTo(33, 44);
            //ab.lineTo(77, 88);
            //ab.lineTo(76, 55);
            //canvas.drawPath(ab, a);//绘制任意多边形
            //canvas.drawArc(new RectF(33,44,333,444), 66, 55, true, a);//绘制圆弧
            //Bitmap ac=((BitmapDrawable)getResources().getDrawable(R.drawable.ic_launcher)).getBitmap();
            //canvas.drawBitmap(ac, 444, 44, a);//绘制图像
            
            //canvas.clipRect(44, 66, 222, 330);//裁剪指定的区域
            //canvas.drawColor(Color.BLUE);
            //canvas.drawText("旋转字", 43, 333, a);
            //canvas.save();
            //canvas.rotate(60,43,333);
            //canvas.drawText("旋转字", 43, 333, a);
            //canvas.restore();//关于画布锁定和解锁,旋转的例子
    

    -----------------------------------------------------------------------------------

    android群英传中对canvas的介绍

    1:Canvas.save(),Canvas.restore(),Canvas.translate(),Canvas.rotate()这四个方法的介绍如下:

    Canvas.save()这个方法,从字面上可以理解为保存画布,它的作用就是将之前的所有已绘制图像保存起来,让后续的操作就好像在一个新的图层上操作一样,这一点点与photoshop中的图层理解基本一致。
    Canvas.restore()这个方法,则可以理解为photoshop中的合并图层操作,它的作用是将我们在save()之后绘制的所有图像与save()之前的图像进行合并。
    translate()和rotate()方法,就是在调用translate(x,y)方法之后,将原点(0,0)移动到(x,y)。之后的所有绘图操作都将以(x,y)为原点执行。同理totate()方法也是一样的,它将坐标系旋转了一定的角度。

    2:Layer图层

    在android中通过调用saveLayer()方法,saveLayerAlpha()方法创建一个图层,使用restore()方法,restoreToCount()方法合并所有图层。创建图层的时候,后面所有的操作都发生在这个图层上。saveLayerAlpha()的第五个参数的取值如果是0比表示完全透明,127表示半透明,255表示完全不透明。示例代码如下:

            canvas.drawCircle(300,300,200,paint);
            canvas.saveLayerAlpha(0,0,600,600,127);
            paint.setColor(Color.GREEN);
            canvas.drawCircle(300,300,300,paint);
            canvas.restore();
    

    图如下所示:


    3:PorterDuffXfermode(参考文章:https://www.jianshu.com/p/0f64daf202f2)


    示例代码如下:

    ...
            canvas.saveLayer(0,0,canvas.getWidth(),canvas.getHeight(),paint);//必须要新建一个图层才能看到混合后的效果了
            canvas.drawCircle(0,0,bitmap.getWidth()/2,paint);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(bitmap,0,0,paint);
            paint.setXfermode(null);// 还原混合模式
            canvas.restore();//合并图层
    ...
    

    效果如下:


    4:Shader,着色器,渲染器,Shader包括:BitmapShader(位图Shader),LinearGradient(线性Shader),RadialGradient(光速Shader),SweepGradient(梯度Shader),ComposeShader(混合Shader)

    4.1:BitmapShader的使用,填充模式有三种CLAMP(拉伸),REPEAT(重复),MIRROR(镜像),示例代码如下:

     paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
            canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, canvas.getWidth() / 2 > canvas.getHeight() / 2 ? canvas.getHeight() / 2 : canvas.getWidth() / 2, paint);
    

    结果如下所示:



    4.2:LinearGradient的使用,示例代码如下:

     paint.setShader(new LinearGradient(0,0,canvas.getWidth(),canvas.getHeight(),Color.BLUE,Color.GREEN, Shader.TileMode.CLAMP));
            canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, canvas.getWidth() / 2 > canvas.getHeight() / 2 ? canvas.getHeight() / 2 : canvas.getWidth() / 2, paint);
    

    结果如下所示:


    小技巧:Marix.setScale(1F,-1F)可以实现图片的垂直翻转。

    5:PathEffect

    5.1:DiscretePathEffect,使用这个效果之后,线段上就会产生许多杂点

            paint.setPathEffect(new DiscretePathEffect(3f,5f));
            Path path=new Path();
            path.moveTo(0,canvas.getHeight()/2);
            path.lineTo(canvas.getWidth()/3,0);
            path.lineTo(canvas.getWidth()/3*2,canvas.getHeight());
            path.lineTo(canvas.getWidth(),0);
            canvas.drawPath(path,paint);
    

    效果图如下:



    5.2:DashPathEffect,这个效果可以用来绘制虚线,用一个数组来设置各个点之间的间隔,此后绘制虚线时就重复这样的间隔进行绘制,另一个参数则用来控制绘制时数组的一个偏移量,通常可以通过设置值来实现路径的动态效果。

      paint.setPathEffect(new DashPathEffect(new float[]{20,10,5,10},0));
    

    效果图如下:



    5.3:PathDashPathEffect,这个效果和DashPathEffect效果类似,只不过它的功能更加强大,可以设置显示点的图形,即方形点的虚线,圆形点的虚线。

            Path path1=new Path();
            path1.addRect(0,0,8,8,Path.Direction.CCW);
            paint.setPathEffect(new PathDashPathEffect(path1,12f,0,PathDashPathEffect.Style.ROTATE));
    

    效果图如下:



    5.4:CornerPathEffect,就是将拐角处变得圆滑,具体圆滑的程度,则由参数决定。

     paint.setPathEffect(new CornerPathEffect(30));
    

    效果图如下:



    5.5:ComposePathEffect,将任意两种路径特效组合起来形成一个新的效果。

            PathEffect pathEffect=new CornerPathEffect(30);
            PathEffect pathEffect1=new DashPathEffect(new float[]{20,10,5,10},0);
            paint.setPathEffect(new ComposePathEffect(pathEffect,pathEffect1));
    

    效果图如下:



    5.6:SumPathEffect,将任意两种路径特效组合起来形成一个新的效果。

            PathEffect pathEffect=new CornerPathEffect(30);
            PathEffect pathEffect1=new DashPathEffect(new float[]{20,10,5,10},0);
            paint.setPathEffect(new SumPathEffect(pathEffect,pathEffect1));
    

    效果图如下:


    相关文章

      网友评论

          本文标题:canvas的使用

          本文链接:https://www.haomeiwen.com/subject/dzqyhftx.html