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来代替。

时间: 2024-09-29 23:07:34

android clipRect Op.xxx各个参数理解的相关文章

[深入理解Android卷一 全文-第二章]深入理解JNI

由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. (出版社排版好的PDF版正在向出版社申请,到时候会通过CSDN下载资源发布) 第2章  深入理解JNI 本章主要内容 ·  通过一个实例,介绍JNI技术和在使用中应注意的问题. 本章涉及的源代码文件名及位置 下面是本章分析的源码文件名及其位置. ·  MediaScanner.java framework/b

[深入理解Android卷二 全文-第八章]深入理解ContentService和AccountManagerService

由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容 第8章  深入理解ContentService和AccountManagerService 本章主要内容: ·  介绍ContentService ·  介绍AccountManagerService 本章所涉及的源代码文件名及位置: ·  SystemServer.java frameworks/base/s

[深入理解Android卷一全文-第八章]深入理解Surface系统

由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版.而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. 第8章  深入理解Surface系统 本章主要内容 ·  具体分析一个Activity的显示过程. ·  具体分析Surface. ·  具体分析SurfaceFlinger. 本章涉及的源代码文件名称及位置: · ActivityThread.java framework/base/core/java/an

[深入理解Android卷一全文-第十章]深入理解MediaScanner

由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在OSC博客中全文转发这两本书的全部内容. 第10章 深入理解MediaScanner 本章主要内容 ·  介绍多媒体系统中媒体文件扫描的工作原理. 本章涉及的源代码文件名及位置 下面是本章分析的源码文件名及其位置. ·  MediaProvider.java packages/providers/MediaProvider/MediaProvider.

[深入理解Android卷一全文-第九章]深入理解Vold和Rild

由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容. 第9章  深入理解Vold和Rild 本章主要内容 ·  介绍Vold. ·  介绍Rild. 本章涉及的源代码文件名称及位置 下面是本章分析的源码文件名及其位置. ·  Main.cpp system/vold/Main.cpp ·  NetlinkManager.cpp system/vold/Netli

android中padding和margin的理解

在android安排控件布局时,padding和margin经常被用到. 其具体解释可以通过一张图展现,如下, 两个属性表示的意义与web编程相同. 深入理解: padding约束的是控件或布局显示的内容距离边框的距离,沿垂直边框向内压缩,padding越大,内容显示控件越小: margin这是沿垂直边框向外延伸的距离, 它的意思就是给控件加了一个一定距离的空白边,显示效果只与值大小正负相关,与其他元素边界无关. 值得注意的是,padding值的范围[0,任意正数](默认为0),而margin的

Android measure和layout的一点理解

首先,推荐文章,http://blog.csdn.net/hqdoremi/article/details/9980481,http://www.docin.com/p-571954086.html 我理解measure的作用有2个:一个就是调用子view的measure函数,生成他们的高度和宽度,以便在自己的layout阶段参考:另一个是为父view提供关于自己的测量的width和height(这个宽度和高度往往和子view的测量高度和宽度有关),以便父view在layout阶段参考. lay

Android Activity 生命周期的透彻理解

说来惭愧,虽然已经做了一年多的android开发,但是最近被人问起activity的生命周期的时候,却感觉自己并不能很自信很确定的回答对方的问题,对activity的生命周期的理解还不透彻啊.     既然发现了问题,那咱就得解决问题,不就个生命周期,能有多复杂. 首先看看android developers 网上的activity的生命周期图:      activity启动的时候:onCreate ---> onStart ---> onResume 这个过程不用多说,大家都知道.这里主要

Android开发--Activity生命周期回顾理解

Activity和Servlet一样,都用了回调机制.我们通过类比servlet来学习Activity.当一个servlet开发出来之后,该servlet运行于Web服务器中.服务器何时创建servlet的实例,何时调用servlet的方法向用户生成响应,程序员无法控制,这种回调由服务器自行决定.Activity也一样,被开发出来,开发者只要在AndroidManifest.xml文件配置该Activity即可.至于该Activity何时被实例化,它的方法何时被调用,对开发者来说完全是透明的.