android clipRect Op.xxx各个参数理解
有点小啰嗦的一篇学习笔记,可以直接看最后得出的结论:前面的各种图片和说明都是为最后的结论服务的
1)剪切:和平常画图工具剪切的作用一样,在画布上剪切一个区域,比如剪切一个Rect区域,画布canvas其余的部分都丢掉,之后所有的画图都在这个Rect区域内进行(如果不涉及save和restore方法)。
2)clip进行剪切的时候,不会影响之前已经画好的图形。
3)剪切是对canvas的操作,而不是在canvas上的图进行操作。
为了说明这几点,下面进行一下说明。
步骤1) 在剪切之前绘制一个全屏的蓝色的矩形。
2)定义剪切的矩形Rect区域,并进行剪切
3)设置剪切过后画布颜色为红色
运行的效果如下图所示:此时剪切过后画布的区域就是剪切的Rect区域,虽然剪切掉了canvas上面和下面的一部分,但是仍然会把途中所示的蓝色部分显示出来而不会剪切掉:也就是如上所说不会影响之前已经画好的图形。

代码如下:
protected void onDraw(Canvas canvas) {
int width = getMeasuredWidth();
int height = getMeasuredHeight();
Paint paint = new Paint();
paint.setColor(Color.BLUE);
//全屏绘制一个蓝色的矩形画面
canvas.drawRect(0, 0,width,height,paint);
//定义剪切的Rect区域
Rect rect = new Rect();
rect.left = 0;
rect.top = 300;//左上角(0,300)
rect.right = width;
rect.bottom = height/2; //右下角(width,height)
//进行剪切
canvas.clipRect(rect)
canvas.drawColor(Color.RED);
}
上面的clipRect是只有一个参数的(默认为INTERSECT,下面看看它的重载方法Cliprect(rect,OP.xx)第二个参数以及各个参数的含义和运行效果:
开始之前做些准备工作:
区域A:剪切之前的画布区域
区域B:当前要剪切的区域,也就是clipRect的第一个参数所表示的区域
在没有直接写代码测试之前对这些字段的翻译和查阅写数学资料并对Op.xxx的各种字段在心里做了如下假设:
XOR:异或运算,相同为0(false),不用为1(true),也就是两个区域重叠的地方为0,不同的地方为1,剪切过后的画布的区域就是两个区域不重叠的部分。
INTERSECT:交集运算,剪切过后的画布区域就是两个区域的交集区域。
REPLACE:这个有待验证,不明所以,从字面意思来说是代替的意思,应该就是用B的区域代替A的区域,所以剪切过后的画布区域可能就是只剩下B的区域,当然这个只是假设,有待下面的验证过。
DIFFERENCE:差集运算,剪切过后的画布的区域就是A-B
REVERSE_DIFFERENCE:差集运算,REVERSE为反向,逆向的意思,不难猜出剪切过后的画布区域是B-A的区域
UNION:并集运算,剪切过后的画布区域就是A和B的区域相加,当然重叠的地方只计算一次
下面就写程序注意验证上面的结果和得出相应的结论
先是全集和子集的情况:此时A为全集区域,B为A的子集

a) Op.DIFFERENCE:即将剪切的区域(设置B)与当前canvas(设置A)之间的差集,剪切过后还剩下的画布canvas区域就是A-B的区域,看看运行结果
步骤还是之前的步骤,只是把canvas.clipRect(rect)改成canvas.clipRect(rect,Op.DIFFERENCE);运行结果如下:<喎�"/kf/ware/vc/"
target="_blank"
class="keylink">vcD4KPHA+PGltZyBzcmM9"/uploadfile/Collfiles/20150212/2015021208423342.png"
alt="\">
b) Op.REVERSE_DIFFERENCE:对比DIFFERENCE取A-B,REVERSE是相反的意思,所以为B-A,因为B为A的子集,所以该差集不存在,所以运行结果为下:

c)
Op.XOR:两个区域进行异或运算,异或运算的规则是:“相同为0(false),不同为1(true)”,当两个区域进行异或的时候,很显然“区域重叠的地方为0,不重叠的地方为1”,剪切过后剩下的画布canvas的区域就是不重叠的地方所在的区域,看看运行结果

d) Op.UNION 取A和B的并集,所以运行结果为下图:

e) Op.INTERSECT 取A和B的交集,因为上面的程序中A是全屏的画布范围,而B在A里面,所以剪切的结果为下图所示,所以说交集为B的范围

f) Op.REPLACE,运行效果如下

通过全集和子集的运行效果来看,REPLACE应该就是跟上面设想的一样,其余的倒是跟设想的结论一样。
所以我就测试了非全集和子集的情况
此时A区域和B区域的关系如图,C为A和B的交集区域:

测试画图步骤:
1)绘制一个蓝色的矩形面
2)定义A的Rect对象(第一次要剪切的区域),并开始剪切
3)定义B的rect对象并开始剪切,并且调用clipRect(rect,Op.xxx)来看不用xxx下剪切的效果
4)把剪切过后的画布设置为红色
上面步骤的代码如下:
int width = 1000;
int height =1000;
Paint paint = new Paint();
paint.setColor(Color.BLUE);
//全屏绘制一个蓝色的矩形画面
canvas.drawRect(0, 0,width,height,paint); //定义区域A的rect对象
Rect rect = new Rect();
rect.left =100;
rect.top = 100;//左上角(0,300)
rect.right = 300;
rect.bottom = 300; //右下角(width,hei
//剪切为A区域
canvas.clipRect(rect);//同clipRect //设置b的rect对象
rect.left =200;
rect.top = 200;//左上角(0,300)
rect.right = 400;
rect.bottom = 400; //右下角(width,height)
canvas.clipRect(rect,Op.xxxx); //把剪切过后的画布设置红色
canvas.drawColor(Color.RED);
a) DIFFERENCE的情况下的运行效果(A-B的差集):也就是A区域去掉C区域

b) REVERSE_DIFFERENCE的运行效果如下图(B-A的差集):也就是B区域去掉C区域

c) UNION 的运行结果 (A和B的并集)

d) INTERSECT (交集运算)此时画布只剩下C区域可以显示,所以运行结果如下

e)XOR 异或运算,剪切过后的结果为A和B区域不重叠的区域

f)REPLACE 这个运算结果是什么呢?就是B区域,也就是剪切过后的结果只保留B区域,这也就是REPLACE代替或者替换的含义:当前还没被剪切的区域A被即将要剪切的区域B来代替。

结论:
XOR:异或运算,相同为0(false),不用为1(true),也就是两个区域重叠的地方为0,不同的地方为1,剪切过后的画布的区域就是两个区域不重叠的部分。
INTERSECT:交集运算,剪切过后的画布区域就是两个区域的交集区域。
DIFFERENCE:差集运算,剪切过后的画布的区域就是A-B
REVERSE_DIFFERENCE:差集运算,REVERSE为反向,逆向的意思,不难猜出剪切过后的画布区域是B-A的区域
UNION:并集运算,剪切过后的画布的区域为A+B的区域
REPLACE:也就是剪切过后的结果只保留B区域,这也就是REPLACE代替或者替换的含义:当前还没被剪切的区域A被即将要剪切的区域B来代替。
android clipRect Op.xxx各个参数理解的更多相关文章
- Android 手写Binder 教你理解android中的进程间通信
关于Binder,我就不解释的太多了,网上一搜资料一堆,但是估计还是很多人理解的有困难.今天就教你如何从 app层面来理解好Binder. 其实就从我们普通app开发者的角度来看,仅仅对于androi ...
- Android高手进阶:Adapter深入理解与优化
一般是针对包含多个元素的View,如ListView,GridView,ExpandableListview,的时候我们是给其设置一个Adapter.Adapter是与View之间提供数据的桥梁,也是 ...
- 对于android触摸事件模型的一些理解
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- [深入理解Android卷一全文-第八章]深入理解Surface系统
由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版.而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. ...
- android.intent.action.MAIN 与 android.intent.category.LAUNCHER 的验证理解 (转)
原文地址:android.intent.action.MAIN 与 android.intent.category.LAUNCHER 的验证理解 作者: 第一种情况:有MAIN,无LAUNCHER,程 ...
- Android Studio 重写方法时参数命名异常
Android Studio 重写方法时参数命名异常 Android Studio 重写方法时参数名称乱掉可以通过下载相应源码解决
- request.getParameter(“xxx”)的参数的取值
request.getParameter(“xxx”)的参数的取值的几种可能: 1. Html中form表单中标签的name属性: <form name="form" met ...
- Android Studio:xxx is not an enclosing class 错误的解决方法
Android Studio:xxx is not an enclosing class 错误的解决方法 这个问题一般出现在内部类中,若要创建内部类的实例,需要有外部类的实例才行,或者是将内部类设置为 ...
- [深入理解Android卷一全文-第十章]深入理解MediaScanner
由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该由于纸质媒介的问题而中断.所以我将在CSDN博客中全文转发这两本书的全部内容. ...
随机推荐
- VC6.0与Office2007~2010不兼容问题及解决方法
一.问题描述 启动打开文件对话框中,在 Visual C++ 使用的键盘快捷键或从文件菜单上将导致以下错误: 在 DEVSHL 中的访问冲突 (0xC0000005).在 0x5003eaed 的 D ...
- 静态方法中不能使用 $this
忽略了一个问题,$this 代表当前对象!! 静态方法中应该使用 类名 . self 或者 static 关键字来代替! static public function get_info($id) { ...
- PTA 11-散列1 电话聊天狂人 (25分)
题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/722 5-14 电话聊天狂人 (25分) 给定大量手机用户通话记录,找出其中通话次数 ...
- Struts has detected an unhandled exception异常
近期在写struts框架的时候会时不时的出现这个异常,多次实验以后发现,目前解决的方法只能通过重新部署项目再重新启动服务器解决,通常这个异常会出现在DMI即动态方法调用过程中.
- 【Luogu】P1486郁闷的出纳员(Splay)
题目链接 名副其实的调了一下午…… 每做一道题都是对我那不规范的Splay代码的刀刻斧凿一般的修正啊…… Splay.如果有一批员工不干了,那就找还能干的薪水最少的员工,把它splay到根,删除它的左 ...
- [AtCoderContest075F]Mirrored
[AtCoderContest075F]Mirrored 试题描述 For a positive integer \(n\), we denote the integer obtained by re ...
- [LOJ#516]「LibreOJ β Round #2」DP 一般看规律
[LOJ#516]「LibreOJ β Round #2」DP 一般看规律 试题描述 给定一个长度为 \(n\) 的序列 \(a\),一共有 \(m\) 个操作. 每次操作的内容为:给定 \(x,y\ ...
- bzoj1023【SHOI2008】cactus仙人掌图
题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1023 求一棵仙人掌的直径 sol :orz YDC神犇 http://ydcydcy1.blo ...
- Java 线程池的原理与实现学习(三)
一简介 线程的使用在java中占有极其重要的地位,jdk1.4及其之前的jdk版本,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观,Jdk1.5之后加入了java.util.c ...
- faster-rcnn 目标检测 数据集制作
本文的目标是制作目标检测的数据集 使用的工具是 python + opencv 实现目标 1.批量图片重命名,手动框选图片中的目标,将目标框按照一定格式保存到txt中 图片名格式(批量) .jpg . ...