canvas 还提供裁剪的功能。

裁剪功能由Canvas提供的一系列的clip...方法 和quickReject方法来完成。 前面已经提到,真正提供可绘制区域的是Canvas内部的mutable bitmap。 Canvas更像是一个图层,我们只能在这上面的图层来绘制东西。

1、首先介绍Region类

Region,中文意思即区域的意思,它表示的是canvas图层上的某一块封闭的区域。

[java] view plaincopy
  1. /**构造方法*/
  2. public Region()  //创建一个空的区域
  3. public Region(Region region) //拷贝一个region的范围
  4. public Region(Rect r)  //创建一个矩形的区域
  5. public Region(int left, int top, int right, int bottom) //创建一个矩形的区域
  6. /**一系列set方法,这些set方法,和上面构造方法形式差不多*/
  7. public void setEmpty() {
  8. public boolean set(Region region)
  9. public boolean set(Rect r)
  10. public boolean set(int left, int top, int right, int bottom)
  11. /*往一个Region中添加一个Path只有这种方法,参数clip代表这个整个Region的区域,在在里面裁剪出path范围的区域*/
  12. public boolean setPath(Path path, Region clip) //用指定的Path和裁剪范围构建一个区域
  13. /**几个判断方法*/
  14. public native boolean isEmpty();//判断该区域是否为空
  15. public native boolean isRect(); //是否是一个矩阵
  16. public native boolean isComplex();//是否是多个矩阵组合
  17. /**一系列的getBound方法,返回一个Region的边界*/
  18. public Rect getBounds()
  19. public boolean getBounds(Rect r)
  20. public Path getBoundaryPath()
  21. public boolean getBoundaryPath(Path path)
  22. /**一系列的判断是否包含某点 和是否相交*/
  23. public native boolean contains(int x, int y);//是否包含某点
  24. public boolean quickContains(Rect r)   //是否包含某矩阵
  25. public native boolean quickContains(int left, int top, int right,
  26. int bottom) //是否没有包含某矩阵
  27. public boolean quickReject(Rect r) //是否没和该矩阵相交
  28. public native boolean quickReject(int left, int top, int right, int bottom); //是否没和该矩阵相交
  29. public native boolean quickReject(Region rgn);  //是否没和该矩阵相交
  30. /**几个平移变换的方法*/
  31. public void translate(int dx, int dy)
  32. public native void translate(int dx, int dy, Region dst);
  33. public void scale(float scale) //hide
  34. public native void scale(float scale, Region dst);//hide
  35. /**一系列组合的方法*/
  36. public final boolean union(Rect r)
  37. public boolean op(Rect r, Op op) {
  38. public boolean op(int left, int top, int right, int bottom, Op op)
  39. public boolean op(Region region, Op op)
  40. public boolean op(Rect rect, Region region, Op op)

上面几乎是Region的所有API,很好理解,主要说明一下最后的一组关于Region组合的方式。组合即当前的Region和另外的一个Region组合,可以用不同的Op方式来进行组合。

Op是一个枚举,定义在Region类中。

[java] view plaincopy
  1. 假设用region1  去组合region2
  2. public enum Op {
  3. DIFFERENCE(0), //最终区域为region1 与 region2不同的区域
  4. INTERSECT(1), // 最终区域为region1 与 region2相交的区域
  5. UNION(2),      //最终区域为region1 与 region2组合一起的区域
  6. XOR(3),        //最终区域为region1 与 region2相交之外的区域
  7. REVERSE_DIFFERENCE(4), //最终区域为region2 与 region1不同的区域
  8. REPLACE(5); //最终区域为为region2的区域
  9. }

ApiDemo中已经提供了一个关于组合的例子,在最后面给出。

Android还提供了一个RegionIterator来对Region中的所有矩阵进行迭代,可以使用该类,获得某个Region的所有矩阵。比较简单。

2、什么是裁剪

裁剪Clip,即裁剪Canvas图层,我们绘制的东西,只能在裁剪区域的范围能才能显示出来。

[java] view plaincopy
  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. Paint paint=new Paint();
  4. canvas.save();
  5. canvas.clipRect(new Rect(100,100,300,300));
  6. canvas.drawColor(Color.BLUE);//裁剪区域的rect变为蓝色
  7. canvas.drawRect(new Rect(0,0,100,100), paint);//在裁剪的区域之外,不能显示
  8. canvas.drawCircle(150,150, 50, paint);//在裁剪区域之内,能显示
  9. canvas.restore();
  10. }

裁剪并不像Matrix变换,它相对于mutable bitmap的坐标是不会改变的。所以超出裁剪区域的绘制不会被显示

3、裁剪的保存和回滚

在之前已经提到了,canvas.save()和canvas.restore()不仅对matrix有效,同样对clip有类似的效果。

4、裁剪的方式

Canvas提供了三种裁剪的方式:

1、最基本的clipRect,裁剪一个矩形

2、clipPath,裁剪Path包括的范围,Path所包括的范围不是空的才有效。

3、clipRegion。

Region在前面已经介绍过了,其实Region就是一个对区域组合的一个封装。但是它和clipRect和clipPath的最大区别在于下面:

[java] view plaincopy
  1. Note that unlike
  2. clipRect() and clipPath() which transform their arguments by the
  3. current matrix, clipRegion() assumes its argument is already in the
  4. coordinate system of the current layer's bitmap, and so not
  5. transformation is performed.

与clipRect和clipPath要使用当前的matrix进行变换不同。clipRegion不会进行转换。也就是说canvas的matrix对clipRegion没有影响。

[java] view plaincopy
  1. Paint paint=new Paint();
  2. canvas.scale(0.5f, 0.5f);
  3. canvas.save();
  4. canvas.clipRect(new Rect(100,100,200,200));//裁剪区域实际大小为50*50
  5. canvas.drawColor(Color.RED);
  6. canvas.restore();
  7. canvas.drawRect(new Rect(0,0,100,100), paint);//矩形实际大小为50*50
  8. canvas.clipRegion(new Region(new Rect(300,300,400,400)));//裁剪区域实际大小为100*100
  9. canvas.drawColor(Color.BLACK);

可以看到,Canvas的变换 对clipRegion没有作用。

ApiDemo中关于组合的例子:

[java] view plaincopy
  1. public class Clipping extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(new SampleView(this));
  6. }
  7. private static class SampleView extends View {
  8. private Paint mPaint;
  9. private Path mPath;
  10. public SampleView(Context context) {
  11. super(context);
  12. setFocusable(true);
  13. mPaint = new Paint();
  14. mPaint.setAntiAlias(true);
  15. mPaint.setStrokeWidth(6);
  16. mPaint.setTextSize(16);
  17. mPaint.setTextAlign(Paint.Align.RIGHT);
  18. mPath = new Path();
  19. }
  20. private void drawScene(Canvas canvas) {
  21. canvas.clipRect(0, 0, 100, 100);
  22. canvas.drawColor(Color.WHITE);
  23. mPaint.setColor(Color.RED);
  24. canvas.drawLine(0, 0, 100, 100, mPaint);
  25. mPaint.setColor(Color.GREEN);
  26. canvas.drawCircle(30, 70, 30, mPaint);
  27. mPaint.setColor(Color.BLUE);
  28. canvas.drawText("Clipping", 100, 30, mPaint);
  29. }
  30. @Override
  31. protected void onDraw(Canvas canvas) {
  32. canvas.drawColor(Color.GRAY);
  33. canvas.save();
  34. canvas.translate(10, 10);
  35. drawScene(canvas);
  36. canvas.restore();
  37. canvas.save();
  38. canvas.translate(160, 10);
  39. canvas.clipRect(10, 10, 90, 90);
  40. canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE);
  41. drawScene(canvas);
  42. canvas.restore();
  43. canvas.save();
  44. canvas.translate(10, 160);
  45. mPath.reset();
  46. canvas.clipPath(mPath); // makes the clip empty
  47. mPath.addCircle(50, 50, 50, Path.Direction.CCW);
  48. canvas.clipPath(mPath, Region.Op.REPLACE);
  49. drawScene(canvas);
  50. canvas.restore();
  51. canvas.save();
  52. canvas.translate(160, 160);
  53. canvas.clipRect(0, 0, 60, 60);
  54. canvas.clipRect(40, 40, 100, 100, Region.Op.UNION);
  55. drawScene(canvas);
  56. canvas.restore();
  57. canvas.save();
  58. canvas.translate(10, 310);
  59. canvas.clipRect(0, 0, 60, 60);
  60. canvas.clipRect(40, 40, 100, 100, Region.Op.XOR);
  61. drawScene(canvas);
  62. canvas.restore();
  63. canvas.save();
  64. canvas.translate(160, 310);
  65. canvas.clipRect(0, 0, 60, 60);
  66. canvas.clipRect(40, 40, 100, 100, Region.Op.REVERSE_DIFFERENCE);
  67. drawScene(canvas);
  68. canvas.restore();
  69. }
  70. }
  71. }

效果图:

5、裁剪的一个小用处

[java] view plaincopy
  1. public class ClippingRegion extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(new SampleView(this));
  6. }
  7. private class SampleView extends View {
  8. private Bitmap mBitmap;
  9. private int limitLength = 0;
  10. private int width;
  11. private int heigth;
  12. private static final int CLIP_HEIGHT = 30;
  13. private boolean status = HIDE;//显示还是隐藏的状态,最开始为HIDE
  14. private static final boolean SHOW = true;//显示图片
  15. private static final boolean HIDE = false;//隐藏图片
  16. public SampleView(Context context) {
  17. super(context);
  18. mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image1);
  19. limitLength = width = mBitmap.getWidth();
  20. heigth = mBitmap.getHeight();
  21. }
  22. @Override
  23. protected void onDraw(Canvas canvas) {
  24. Region region = new Region();
  25. int i = 0;
  26. while (i * CLIP_HEIGHT <= heigth) {//计算clip的区域
  27. if (i % 2 == 0) {
  28. region.union(new Rect(0, i * CLIP_HEIGHT, limitLength, (i + 1) * CLIP_HEIGHT));
  29. } else {
  30. region.union(new Rect(width - limitLength, i * CLIP_HEIGHT, width, (i + 1)
  31. * CLIP_HEIGHT));
  32. }
  33. i++;
  34. }
  35. canvas.clipRegion(region);
  36. canvas.drawBitmap(mBitmap, 0, 0, new Paint());
  37. if (status == HIDE) {//如果此时是隐藏
  38. limitLength -= 5;
  39. if(limitLength<=0)
  40. status=SHOW;
  41. } else {//如果此时是显示
  42. limitLength += 5;
  43. if(limitLength>=width)
  44. status=HIDE;
  45. }
  46. invalidate();
  47. }
  48. }
  49. }

效果就是一直这样交叉的隐藏和显示图片

转自:http://blog.csdn.net/lonelyroamer/article/details/8349601

regin,clip Android相关推荐

  1. Android输入法遮挡了输入框,使用android:fitsSystemWindows=“true“后界面顶部出现白条解决方案

    Android输入法遮挡了输入框,使用android:fitsSystemWindows="true"后界面顶部出现白条解决方案 参考文章: (1)Android输入法遮挡了输入框 ...

  2. Flutter配置好后,在Android Studio中找不到设备,no devices

    Flutter配置好后,在Android Studio中找不到设备,no devices 完成Flutter的Android配置之后,连上设备,运行flutter doctor,发现已经识别了一个可用 ...

  3. github snap android,GitHub - albuer/heapsnap: HeapSnap 是一个定位内存泄露的工具,适用于Android平台。...

    HeapSnap 1.HeapSnap 是什么 HeapSnap 是一个定位内存泄露的工具,适用于Android平台. 主要特性如下: 对系统负载低 不需要修改目标进程的源代码 支持Andoroid上 ...

  4. 最简单也最难——如何获取到Android控件的高度,获取android控件

    最简单也最难--如何获取到Android控件的高度,获取android控件 问题 如何获取一个控件的长和高,相信很多朋友第一眼看见这个问题都会觉得很简单,直接在onCreate里面调用getWidth ...

  5. (GO_GTD_1)基于OpenCV和QT,建立Android图像处理程序

    一.创建新QT工程 一定要是全英文路径,比如"E:\android_qt_opencv\GO_GTD" 由于我们在安装的时候,选择android的工具链,所以在这里会出现以下选择, ...

  6. video.js android,VideoJS + HTML5自动播放失败,适用于Android 2.3+和IOS 4+

    我的VideoJS和HTML5项目针对更新的Web浏览器(较新版本的FireFox和Chrome)以及移动浏览器(Android2.3 +和IOS4 +).VideoJS + HTML5自动播放失败, ...

  7. android serialport new 软件退出_基于Android9.0,了解Android启动流程

    先记住四个进程和三种方式. **四个进程** 1.Launcher进程 2.system_server进程 3.App进程 4.Zygote进程 **三种方式** 1.Binder方式 2.Socke ...

  8. 谷歌发布最新版安卓Android,谷歌发布安卓 9 正式版,代号 Android Pie

    爱搞机 8 月 7 日消息,据外媒报道,北京时间今日凌晨,谷歌开始向用户推送安卓 Android Pie 正式版,除了确定新系统的代号为 Pie(派)之外,谷歌还将原本的安卓 9.0 称作 Andro ...

  9. java android长连接_基于Java Socket的自定义协议,实现Android与服务器的长连接(一)...

    一.基础知识准备 在正式给大家介绍自定义协议之前,我们先对网络传输和协议解析的相关知识点做一个基本的介绍,尽管这些知识点我们在学校里学过,但难免会有所遗忘,这里先做一个简单的介绍,以便对后文的内容理解 ...

最新文章

  1. Spring 如何初始化泛型类实例
  2. 澎湖县地产泡沫的破灭
  3. C++内存管理与分配方式
  4. 解决Ubuntu下 Could NOT find CURL (missing: CURL_LIBRARY CURL_INCLUDE_DIR)
  5. 计算机怎么远程桌面,电脑远程桌面如何连接 电脑远程桌面连接方法【详解】...
  6. android 缓存头像,android 实现类似微信缓存和即时更新好友头像示例
  7. java和js实现电话号码部分隐藏
  8. 95后夜猫子报告:三成熬夜到1点 夜间最爱追《乡村爱情》
  9. Linux学习笔记5 - Shell编程(类似于Windows下的批处理)
  10. QT将英文星期转为中文星期
  11. echarts年龄饼图_ECharts中饼图的操作
  12. linux卸载exe文件怎么恢复,linux中误删除程序包恢复实例
  13. [iOS]在xcode的iOS虚拟机中对BLE(蓝牙4.0)进行调试
  14. (教程)教你如何自己办理商标注册事宜
  15. android关闭本应用的通知声音代码,关于android:当我的应用取消通知时,播放带有FLAG_INSISTENT通知的声音不会停止...
  16. “赋能开发者”高峰论坛暨西安葡萄城30周年庆典隆重举办
  17. 2020下半年,最接地气的字节跳动Android面经分享(已收offer
  18. 操作系统面试题(十二):逻辑地址和物理地址
  19. 杜洋PCB设计视频教程笔记(陆续更新)
  20. 开源超级微同城系统源码 含完整程序代码包+数据库+详细搭建教程

热门文章

  1. ubuntu16.04 护眼神器Redshift
  2. 阿里天池大数据竞赛(一)用ODPS提取特征
  3. 编程的宗派(OOP与FP孰优孰劣)--王垠
  4. 脱水冷冻干燥宠物食品的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  5. 探索 Sa-Token (一) SpringBoot 集成 Sa-Token
  6. React Native 仿 ofo 共享单车 App
  7. xpath中的position()函数使用
  8. Tensorflow中的masking和padding
  9. 华为路由器ospf路由表解读_华为路由如何建立OSPF网络详解
  10. HCIA Storage部分题库