extends:http://blog.csdn.net/lonelyroamer/article/details/8349601

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

1、首先介绍Region类

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

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

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

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

假设用region1 去组合region2

  1. public enum Op {
  2. DIFFERENCE(0), //最终区域为region1 与 region2不同的区域
  3. INTERSECT(1), // 最终区域为region1 与 region2相交的区域
  4. UNION(2), //最终区域为region1 与 region2组合一起的区域
  5. XOR(3), //最终区域为region1 与 region2相交之外的区域
  6. REVERSE_DIFFERENCE(4), //最终区域为region2 与 region1不同的区域
  7. REPLACE(5); //最终区域为为region2的区域
  8. }
  9.  
  1. ApiDemo中已经提供了一个关于组合的例子,在最后面给出。
  2.  
  3. Android还提供了一个RegionIterator来对Region中的所有矩阵进行迭代,可以使用该类,获得某个Region的所有矩阵。比较简单。
  4.  
  5. 2、什么是裁剪
  6.  
  7. 裁剪Clip,即裁剪Canvas图层,我们绘制的东西,只能在裁剪区域的范围能才能显示出来。
  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的最大区别在于下面:

  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没有影响。

  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.  
  8. canvas.drawRect(new Rect(0,0,100,100), paint);//矩形实际大小为50*50
  9.  
  10. canvas.clipRegion(new Region(new Rect(300,300,400,400)));//裁剪区域实际大小为100*100
  11. canvas.drawColor(Color.BLACK);
 

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

ApiDemo中关于组合的例子:

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

效果图:

5、裁剪的一个小用处

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

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

Canvas裁剪Clip和Region、RegionIterator的更多相关文章

  1. Canvas裁剪和Region、RegionIterator

    主要是看这边文章学习:http://blog.csdn.net/lonelyroamer/article/details/8349601 Region.op参数 DIFFERENCE(0), //最终 ...

  2. Android 2D Graphics学习 Region和Canvas裁剪

    1.首先介绍Region类 Region,中文意思即区域的意思,它表示的是canvas图层上的某一块封闭的区域. /**构造方法*/ public Region()  //创建一个空的区域 publi ...

  3. html5 canvas裁剪区域

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. CSS裁剪clip

    × 目录 [1]定义 [2]RECT [3]应用 前面的话 CSS裁剪clip这个属性平时用的不多,但其实它并不是CSS3的新属性,很早就开始出现了.本文将介绍关于clip属性的相关知识 定义 一个绝 ...

  5. 【原创】canvas裁剪上传图片异步提交

    <!DOCTYPE html> canvas裁剪图片,纯前端 裁剪文件 后台返回获取裁剪后的文件

  6. CSS图片裁剪Clip

    CSS Clip 裁剪 可以用它来裁剪一张图片噢. 我们来裁剪一下Google图标,把G字给裁剪下来. 注意这个clip得配合绝对定位才能使用,不然不起效果. rect (top, right, bo ...

  7. [ javascript canvas toDataURL() clip() ] javascript canvas toDataURL() clip() 属性及方法演示

    <!DOCTYPE html> <html lang='zh-cn'> <head> <title>Insert you title</title ...

  8. ArcGIS Engine 图层裁剪 Clip的实现方法

    方法一, 图层对图层裁剪,输出图层 ILayer pLayer; IFeatureLayer pFeatureLayer; IFeatureClass pFeatureClass; IWorkspac ...

  9. 利用canvas裁剪想要的图片

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

随机推荐

  1. 12 go实现几中基本排序算法

    include 冒泡排序 插入排序 快速排序 选择排序 这4种算法的内涵不再做解释了 github地址 冒泡排序算法 func maoPao(intSlice []int) []int { /* 冒泡 ...

  2. ubuntu alsa

    今天要在linux下搞音频编程,在网上查阅了一下资料,网上很多资料都是在linux下直接对/dev/dsp进行编程的,因为在以往的linux系统中,我们是可以通过cat  xxx.wav /dev/d ...

  3. C#静态构造函数调用机制

    https://blog.csdn.net/cjolj/article/details/56329230 若一个类中有静态构造函数,在首次实例化该类或任何的静态成员被引用时,.NET自动调用静态构造函 ...

  4. PHP 5.4 中的traits

    PHP 5.4中的traits,是新引入的特性,中文还真不知道如何准确翻译好.其实际的目的,是为了有的场合想用多继承,但PHP又没多继承,于是就发明了这样的一个东西. Traits (横向重用/多重继 ...

  5. Incorrect column count: expected 1, actual 5,JdbcTemplate queryForList 出错

    spring JdbcTemplate  queryForList 出错 Incorrect column count: expected 1, actual 5 >>>>&g ...

  6. 【Ubuntu】Windows 远程桌面连接ubuntu及xrdp的一些小问题(远程桌面闪退、连接失败、tab补全功能,无菜单栏,error - problem connecting )【转】

    转:https://blog.csdn.net/u014447845/article/details/80291678 1.远程桌面闪退,shell可以用的问题:(1)需要在该用户目录创建一个.xse ...

  7. PDF XSS

    漏洞测试: 下面,我们介绍如何把 JavaScript 嵌入到 PDF 文档之中.我使用的是迅捷 PDF 编辑器未注册版本 1.启动迅捷 PDF 编辑器打开一个 PDF 文件,或者使用“创建 PDF ...

  8. Linux应急响应(四):盖茨木马

    0x00 前言 ​ Linux盖茨木马是一类有着丰富历史,隐藏手法巧妙,网络攻击行为显著的DDoS木马,主要恶意特点是具备了后门程序,DDoS攻击的能力,并且会替换常用的系统文件进行伪装.木马得名于其 ...

  9. php-fpm 配置进程池

    什么是 php-fpm :php 是作为一个独立服务存在的,这个服务叫做 php-fpm什么是 php-fpm pool :也就是 php-fpm 的进程池,这个进程池中运行了多个子进程,用来并发处理 ...

  10. vs 2010中如何检查内存泄露

    首先,在文件头添加下面的内容: #ifdef _DEBUG#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)#else# ...