canvas的一些有用的使用小结


canvas可以看做是一台打印机,bitmap是好比纸,paint是墨水,打印机使用不同的墨水在不同的纸上绘制,而canvas本身自带有纸了,但你也可以指定它在你指定的纸上绘制。

1.canvas.save()方法:

这个方法调用后会保存调用这个方法前的状态,相当于调用了这个方法后重新铺上了一个新的图层,之后的绘制会在新的图层,不会对之前的绘制造成影响。

2.canvas.restore(); 方法:

调用了save的方法后在新的图层里绘制,绘制完后调用这个方法会重新回到save之前的图层。所以这里与save的方法是一起使用的,就类似与图层栈的入栈与出栈,所以这个方法调用的次数必须要比save调用的次数少。 这两个方法的作用,举个例子:绘画了一个部分后,想对接下来的绘画具有缩放效果,为了不影响前面的,调用是save的方法,然后使用缩放的方法绘制,绘制后下想返回,就调用这个方法,那么之后的绘制就没有缩放的效果了。


3.canvas.rotate 方法:

这个可以使图层旋转,好处举个例子:画个时钟的刻度,你只要指定一个刻度的绘画线就可以了,然后选择角度继续一样的绘画就可以了,与ps绘画相似。

4.canvas.translate 方法:

这个可以使图层移动,举个例子,你想从某个位置上划线,你不知道终点坐标,只指定划线长度,那么将起点移动到这个位置,那么相当于从(0,0)位置上划线,结合save与restore的方法,可以使绘画很方便。

举个例子:
 int w = getWidth();
        int h = getHeight();
        Paint p = new Paint();
        p.setColor(Color.parseColor("#00bcd4"));
        canvas.drawCircle(w / 2, h / 2, 150, p);
        p.setColor(Color.WHITE);
        canvas.drawCircle(w / 2, h / 2, 140, p);
        p.setColor(Color.BLACK);
        p.setStrokeWidth(4);
        for (int i = 0; i < 12; i++) {
            canvas.drawLine(w / 2 - 140, h / 2, w / 2 - 130, h / 2, p);
            canvas.rotate(360 / 12, w / 2, h / 2);
        }

        canvas.save();
        canvas.translate(w / 2, h / 2);
        canvas.drawLine(0, 0, 20, 0, p);
        canvas.drawLine(0,0,0,50,p);
        canvas.restore();


效果如下:




4.结合Matrix的使用


Matrix的对图像的处理可分为四类基本变换:

Translate 平移变换

Rotate 旋转变换

Scale 缩放变换

Skew 错切变换


5.canvas.clipRect


canvas裁剪:有6种裁剪,分别是:


Region.Op.DIFFERENCE   显示裁剪区以外的部分

测试代码:
<pre name="code" class="java">canvas.drawColor(Color.GRAY);
        Paint p=new Paint();
        canvas.clipRect(50, 50, 200, 300, Region.Op.DIFFERENCE       );
        p.setAntiAlias(true);
        Rect rect=new Rect();
        rect.set(50, 50, 200, 400);
        p.setColor(Color.RED);
        canvas.drawRect(rect, p);
        p.setColor(Color.parseColor("#00bcd4"));
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, 150, p);


 
 

效果如下:




Region.Op.REPLACE     是显示裁剪区以内的部分

测试代码:
<pre name="code" class="java"> canvas.clipRect(50, 50, 200, 300, Region.Op.REPLACE  );
        p.setAntiAlias(true);
        Rect rect=new Rect();
        rect.set(50, 50, 200, 400);
        p.setColor(Color.RED);
        canvas.drawRect(rect, p);
        p.setColor(Color.parseColor("#00bcd4"));
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, 150, p);

 
 
效果如下:




Region.Op.REVERSE_DIFFERENCE   两次裁剪区域的的差集部分:
 Paint p=new Paint();
        canvas.clipRect(50, 50, 200, 300, Region.Op.REVERSE_DIFFERENCE  );
        canvas.clipRect(50, 50, 100, 200, Region.Op.REVERSE_DIFFERENCE  );
        p.setAntiAlias(true);
        Rect rect=new Rect();
        rect.set(50, 50, 200, 400);
        p.setColor(Color.RED);
        canvas.drawRect(rect, p);
        p.setColor(Color.parseColor("#00bcd4"));
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, 150, p);






Region.Op.INTERSECT   两次裁剪区域的交集部分:

代码如下:

<pre name="code" class="java">canvas.drawColor(Color.GRAY);
        Paint p=new Paint();
        canvas.clipRect(50, 50, 200, 300, Region.Op.INTERSECT      );
        canvas.clipRect(50, 50, 100, 200, Region.Op.INTERSECT        );
        p.setAntiAlias(true);
        Rect rect=new Rect();
        rect.set(50, 50, 200, 400);
        p.setColor(Color.RED);
        canvas.drawRect(rect, p);
        p.setColor(Color.parseColor("#00bcd4"));
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, 150, p);

 
 
效果如下:





Region.Op.UNION  两次裁剪的并集


Region.Op.XOR  补集 就是全集的减去交集生育部分显示





6.canvas.clipPath 方法:

注意的是,这里的path应该是一个封闭的路径。

代码如下:

Bitmap b= BitmapFactory.decodeResource(getResources(), R.mipmap.pic);
        canvas.drawColor(Color.GRAY);
        Paint p=new Paint();
        Path path = new Path();
        path.addCircle(getWidth() /2, getHeight()/2,155, Path.Direction.CW);
        canvas.clipPath(path,Region.Op.INTERSECT);

        p.setAntiAlias(true);
        Rect rect=new Rect();
        rect.set(50, 50, 200, 400);
        p.setColor(Color.RED);
        canvas.drawRect(rect, p);
        p.setColor(Color.parseColor("#00bcd4"));
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, 150, p);


效果如下:







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值