Android中的自绘View的那些事儿(六)之 画布裁剪
来源:互联网 发布:如何利用淘宝赚钱 编辑:程序博客网 时间:2024/06/04 19:54
我们在之前的文章中有简单介绍过画布Canvas的使用,它可以使用一系列的draw方法来绘制出各种样式的几何的图形、文字和图片来。今天我们继续探讨Canvas的另一种使用,那就是画布裁剪。什么是画布裁剪?它有点像flash 遮罩层的概念,说白了就是把原来一整块画布裁剪部分出来,然后要绘制出来的东西只能在指定的裁剪区域范围内才能显示出来。
Canvas的裁剪必须要使用save和restore方法:
save: 用于保存Canvas当前的状态。save之后,我们便可以随意对Canvas进行平移、放缩、旋转、错切、裁剪等操作
restore: 用于恢复Canvas之前保存的状态。也就是使save后对Canvas执行的操作对后续的绘制不会造成影响
Canvas的裁剪提供了一些的clip方法:
clipRegion 方法已经不再建议使用
clipPath 裁剪路径,就是指在此路径内绘制
clipRect 裁剪矩形,就是指在此矩形内绘制
示例:
public class MyView extends View { public MyView(Context context) { this(context, null, 0); } public MyView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public MyView(Context context, @Nullable AttributeSet attrs, intdefStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.RED); Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.iron_man); canvas.drawBitmap(bitmap, 0, 0, paint); }}
我们首先来看下正常情况下,我们只在canvas中绘制一张图片。输出效果:
修改onDraw代码:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.RED); int centerX = getWidth() / 2; int centerY = getHeight() / 2; canvas.save(); Path path = new Path(); path.addCircle(centerX, centerY, 300, Path.Direction.CW); canvas.clipPath(path); canvas.clipRect(centerX - 50, 100, centerX + 50, getHeight() - 100,Region.Op.UNION); Bitmap bitmap =BitmapFactory.decodeResource(getResources(),R.mipmap.iron_man); canvas.drawBitmap(bitmap, 0, 0, paint); canvas.restore(); }
代码中,我们在开头和结尾分别使用了canvas.save();和canvas.restore();。然后来看中间部分,canvas.clipPath()和canvas.clipRect()两次裁剪了画布。注意clipRect最后的参数Region.Op.UNION,它是表示两个区域叠加。运行效果:
再修改onDraw代码:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.RED); int centerX = getWidth() / 2; int centerY = getHeight() / 2; canvas.save(); Path path = new Path(); path.addCircle(centerX, centerY, 300, Path.Direction.CW); canvas.clipPath(path); canvas.clipRect(centerX - 50, 100, centerX + 50, getHeight() - 100,Region.Op.UNION); canvas.rotate(45, centerX, centerY); // 旋转 canvas.translate(100, 100); // 平移 canvas.scale(0.5f, 0.5f); // 缩放 canvas.skew(0, 1); // 错切 Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.iron_man); canvas.drawBitmap(bitmap, 0, 0, paint); canvas.restore(); }
本次代码中,我们加入了旋转(rotate)、平移(translate)、缩放(scale)以及错切(skew)效果。运行效果:
注意
在Android4.0及之前的手机中,因为硬件加速等原因,在使用clipPath时很有可能会发生UnsupportedOperationException异常,像下面:
java.lang.UnsupportedOperationExceptionatandroid.view.GLES20Canvas.clipPath(GLES20Canvas.java:287)atcom.myapp.MyCustomView.onDraw(SourceFile:288)at android.view.View.draw(View.java:9310)at android.view.View.getDisplayList(View.java:8773)atandroid.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2298)
所以在使用画布裁剪中最好加入捕捉UnsupportedOperationException异常的处理和系统判断过滤。
- Android中的自绘View的那些事儿(六)之 画布裁剪
- Android中的自绘View的那些事儿(一)
- Android中的自绘View的那些事儿(四)之 ComposeShader组合渲染器的简介
- Android中的自绘View的那些事儿(五)之 遮罩滤镜:BlurMaskFilter 和 EmbossMaskFilter 的简介
- Android中的自绘View的那些事儿(二)之 Shader渲染器和BitmapShader位图渲染器的简介
- Android中的自绘View的那些事儿(三)之 颜色渐变渲染器:LinearGradient、RadialGradient 和 SweepGradient的简介
- C语言的那些事儿之六
- Android自定义View(六)_Canvas之画布操作
- Servlet&JSP的那些事儿(六)
- 网络中的那些事儿(一)之神奇的通讯
- 读书笔记JVM探秘之六:编译器的那些事儿
- Android之使用WebView的那些事儿
- Objective-C语法之static关键字的那些事儿(六)
- Objective-C语法之static关键字的那些事儿(六)
- Objective-C语法之static关键字的那些事儿(六)
- Android“时区”的那些事儿(1)
- 读研的那些事儿(六)
- Android自定义View之画笔与画布
- cocos2d中各种action方法的应用
- 营销运营人员的自我修炼——系列二
- Code+ 2017年12月月赛练习题 晨跑
- 二叉树遍历的非递归Java实现
- powerDesigner绘制类图
- Android中的自绘View的那些事儿(六)之 画布裁剪
- Android-x86 Porting Guide for OPENTHOS Developers
- 1797: [Ahoi2009]Mincut 最小割
- form传递值后台为空
- 测试用例编写设计
- rplidar 使用
- 世界国家中英文对照
- 自学编程需要注意什么?
- xml透明度参照表