Android Canvas API总结和使用方法

Android Canvas API总结和使用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//Canvas 操作函数 2015年5月15日 Android 4.4

int MATRIX_SAVE_FLAG = 0x01;
int CLIP_SAVE_FLAG = 0x02;
int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04;
int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;
int CLIP_TO_LAYER_SAVE_FLAG = 0x10;
int ALL_SAVE_FLAG = 0x1F; 
int DIRECTION_LTR =  0;

Canvas();
Canvas(Bitmap bitmap);

boolean isHardwareAccelerated();
void setBitmap(Bitmap bitmap);
boolean isOpaque();
int getWidth();
int getHeight();
int getDensity();
void setDensity( int density);
int getMaximumBitmapWidth();
int getMaximumBitmapHeight();

//图层保存与恢复操作
int save();    //保存当前图层
int save( int saveFlags);
//保存指定区域图层
//paint为要保存的画笔,restore()后可以用。一般为null
//saveFlags为要保存的内容
int saveLayer(RectF bounds, Paint paint,  int saveFlags);  
int saveLayer( float left,  float top,  float right,  float bottom, Paint paint,  int saveFlags);
//保存指定区域图层,并修改其透明度
int saveLayerAlpha(RectF bounds,  int alpha,  int saveFlags);
int saveLayerAlpha( float left,  float top,  float right,  float bottom,  int alpha,  int saveFlags);
void restore();          //恢复上一层图层
int getSaveCount();      //获得已只在的图层数量
void restoreToCount( int saveCount);   //恢复指定层的图层
//图层变换
void translate( float dx,  float dy);
void scale( float sx,  float sy);
void scale( float sx,  float sy,  float px,  float py);
void rotate( float degrees);
void rotate( float degrees,  float px,  float py);
void skew( float sx,  float sy);   //扭曲
void concat(Matrix matrix);   //Maxrix矩阵变换

void setMatrix(Matrix matrix);
void getMatrix(Matrix ctm);
Matrix getMatrix();
//裁剪
boolean clipRect(RectF rect, Region.Op op);
boolean clipRect(Rect rect, Region.Op op);
boolean clipRect(RectF rect);
boolean clipRect(Rect rect);
boolean clipRect( float left,  float top,  float right,  float bottom, Region.Op op);
boolean clipRect( float left,  float top,  float right,  float bottom);
boolean clipRect( int left,  int top,  int right,  int bottom);
boolean clipPath(Path path, Region.Op op);
boolean clipPath(Path path);
boolean clipRegion(Region region, Region.Op op);
boolean clipRegion(Region region);

DrawFilter getDrawFilter();
void setDrawFilter(DrawFilter filter);
boolean quickReject(RectF rect, EdgeType type);
boolean quickReject(Path path, EdgeType type);
boolean quickReject( float left,  float top,  float right,  float bottom, EdgeType type);
boolean getClipBounds(Rect bounds);
Rect getClipBounds();

//填充RGB
void drawRGB( int r,  int g,  int b);
void drawARGB( int a,  int r,  int g,  int b);
//填充Color
void drawColor( int color);
void drawColor( int color, PorterDuff.Mode mode);
//指定画笔
void drawPaint(Paint paint);
//画点
void drawPoints( float[] pts,  int offset,  int count, Paint paint);
void drawPoints( float[] pts, Paint paint);
void drawPoint( float x,  float y, Paint paint);
//画直线
void drawLine( float startX,  float startY,  float stopX,  float stopY, Paint paint);
void drawLines( float[] pts,  int offset,  int count, Paint paint);   //pts数组里的每两个元素为一个点,每两个点画一条直线
void drawLines( float[] pts, Paint paint);
//画矩形
void drawRect(RectF rect, Paint paint);
void drawRect(Rect r, Paint paint);
void drawRect( float left,  float top,  float right,  float bottom, Paint paint);
//画椭圆
void drawOval(RectF oval, Paint paint);
//画圆
void drawCircle( float cx,  float cy,  float radius, Paint paint);
//画弧,扇形
void drawArc(RectF oval,  float startAngle,  float sweepAngle,  boolean useCenter, Paint paint);
//画圆角矩形
void drawRoundRect(RectF rect,  float rx,  float ry, Paint paint);
//画路径
void drawPath(Path path, Paint paint);
//画位图
void drawBitmap(Bitmap bitmap,  float left,  float top, Paint paint);
void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint);
void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint);
void drawBitmap( int[] colors,  int offset,  int stride,  float x,  float y,  int width,  int height,  boolean hasAlpha,
void drawBitmap( int[] colors,  int offset,  int stride,  int x,  int y,  int width,  int height,  boolean hasAlpha, Paint paint);
void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint);
void drawBitmapMesh(Bitmap bitmap,  int meshWidth,  int meshHeight,  float[] verts,  int vertOffset,  int[] colors,  int colorOffset, Paint paint);
//画顶点
void drawVertices(VertexMode mode,  int vertexCount,  float[] verts,  int vertOffset,  float[] texs,  int texOffset,  int[] colors,  int colorOffset,  short[] indices,  int indexOffset,
//画字
void drawText( char[] text,  int index,  int count,  float x,  float y, Paint paint);
void drawText( String text,  float x,  float y, Paint paint);
void drawText( String text,  int start,  int end,  float x,  float y, Paint paint);
void drawText(CharSequence text,  int start,  int end,  float x,  float y, Paint paint);
//绝对值画字
void drawPosText( char[] text,  int index,  int count,  float[] pos, Paint paint);
void drawPosText( String text,  float[] pos, Paint paint);
//根据路径画字
void drawTextOnPath( char[] text,  int index,  int count, Path path,  float hOffset,  float vOffset, Paint paint);
void drawTextOnPath( String text, Path path,  float hOffset,  float vOffset, Paint paint);
//画图片
void drawPicture(Picture picture);
void drawPicture(Picture picture, RectF dst);
void drawPicture(Picture picture, Rect dst);

Canvas draw系列函数用法示例


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

public  class MyCanvasDrawView  extends View {

private  static  final  String TAG = null;

public MyCanvasDrawView(Context context) {
super(context);

    }

    @Override
protected  void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置背景颜色
        canvas.drawColor(Color.WHITE);
//画弧
        drawMultArc(canvas);
//画路径和文字
        drawPathWithText(canvas);
//画直线
        drawLine(canvas);
//sample
        drawCompass(canvas,  10400);
    }

public  void drawLine(Canvas canvas) {
        Paint paint =  new Paint();
        paint.setColor(Color.YELLOW);
        paint.setStrokeWidth( 5);
float offset =  150 /  6;
float leveOff =  150 /  4;
float[] pts = {600f + offset *  2, 400f - leveOff *  2, 750f - offset *  2, 400f - leveOff *  2,
                       600f + offset, 400f - leveOff , 750f - offset, 400f - leveOff,
                       600f, 400f , 750f, 400f
                      };
        canvas.drawLines(pts , paint);
    }

public  void drawMultArc(Canvas canvas) {
        Paint[] mPaints;
boolean[] mUseCenters;
        RectF[] mRectF;

//边框的画笔
        Paint rectPaint =  new Paint();
        rectPaint.setAntiAlias(true);
        rectPaint.setColor(Color.GRAY);
        rectPaint.setStyle(Paint.Style.STROKE);
        rectPaint.setStrokeWidth( 5);

        mUseCenters =  new  boolean[ 4];
        mPaints =  new Paint[ 4];
        mRectF =  new RectF[ 4];

        initDrawMultArc(mPaints, mUseCenters);

        _drawMultArc(canvas, mPaints, mUseCenters, mRectF, rectPaint);
    }

public  void initDrawMultArc(Paint[] mPaints,  boolean[] mUseCenters) {
//      1. 填充圆弧但不含圆心:
        mPaints[ 0] =  new Paint();
        mPaints[ 0].setAntiAlias(true);
        mPaints[ 0].setStyle(Paint.Style.FILL);
        mPaints[ 0].setColor(0x88FF0000);
        mUseCenters[ 0] = false;

//      2. 填充圆弧带圆心(扇形)
        mPaints[ 1] =  new Paint(mPaints[ 0]);
        mPaints[ 1].setColor(0x8800FF00);
        mUseCenters[ 1] = true;

//      3. 只绘圆周,不含圆心
        mPaints[ 2] =  new Paint(mPaints[ 0]);
        mPaints[ 2].setStyle(Paint.Style.STROKE);
        mPaints[ 2].setStrokeWidth( 4);
        mPaints[ 2].setColor(0x880000FF);
        mUseCenters[ 2] = false;

//      4. 只绘圆周,带圆心(扇形)
        mPaints[ 3] =  new Paint(mPaints[ 2]);
        mPaints[ 3].setColor(0x88888888);
        mUseCenters[ 3] = true;
    }

public  void _drawMultArc(Canvas canvas, Paint[] mPaints,
boolean[] mUseCenters, RectF[] mRectF, Paint rectPaint) {
int rectLeft =  10;
int rectTop =  50;
int width =  150;
int rectRight = rectLeft + width;
int rectBottom = rectTop + width;
int offest = rectLeft + width +  30 ;

//初始化弧形的区域,决定弧形的开关和位置
         for( int i =  0; i <  4; i++) {
            mRectF[i] =  new RectF(rectLeft + i * offest, rectTop, rectRight + i * offest, rectBottom);
        }

        Log.i(TAG,  "mRectF[3] " + mRectF[ 3].left +  " " + mRectF[ 3].bottom);

/**
         * 参数1:弧形的区域
         * 参数2:起始的角度
         * 参数3:弧形的角度
         * 参数4:是否有中心角度
         */

for (  int i =  0; i <  4; i++ ) {
            canvas.drawArc(mRectF[i],  30260, mUseCenters[i], mPaints[i]);
            canvas.drawRect(mRectF[i], rectPaint);
        }
    }

public  void drawPathWithText(Canvas canvas) {
        Paint pathPaint =  new Paint();
        pathPaint.setARGB( 7023818137);
        pathPaint.setStyle(Paint.Style.FILL);
        pathPaint.setAntiAlias(true);
        pathPaint.setStrokeWidth( 5);

        Path path =  new Path();

int pathStartX =  10;
int pathStartY =  250;
int length =  150;
//第一个三角形
        initPath(canvas, pathPaint, path, pathStartX, pathStartY, length);
        canvas.drawPath(path , pathPaint);

//清除path属性
        path.reset();
        pathPaint.setColor(Color.CYAN);
        pathPaint.setStyle(Paint.Style.STROKE);
        pathStartX = length +  50;
//第二个三角形
        initPath(canvas, pathPaint, path, pathStartX, pathStartY, length);
        canvas.drawPath(path , pathPaint);

//第三个图形
        path.reset();
        pathPaint.setColor(Color.DKGRAY);
        pathStartX = (length +  50) *  2;
//逆时针添加一个圆
         //最后一个参数指定构建方法,逆时针和顺时针,并不影响图形效果,但是会影响文字的构建顺序
        path.addCircle(pathStartX +  length /  2 , pathStartY +  length /  2, length /  2, Path.Direction.CCW);
        canvas.drawPath(path , pathPaint);

//设置字体属性
        pathPaint.setStrokeWidth( 1);
        pathPaint.setTextSize( 30);
        pathPaint.setTypeface(Typeface.SERIF);
        canvas.drawTextOnPath( "Android Canvas&Paint", path,  1028, pathPaint);
        pathPaint.setTextSize( 25);
        pathPaint.setStyle(Paint.Style.FILL);
        canvas.drawTextOnPath( "Android", path,  10, - 10, pathPaint);
    }

public  void drawCompass(Canvas canvas,  int startX,  int startY) {

        canvas.save();
        Paint paint;
        paint =  new Paint();  //设置一个笔刷大小是3的黄色的画笔
        paint.setColor(Color.BLACK);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeWidth( 3);

        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        canvas.translate(canvas.getWidth() /  2200);  //移动画纸的坐标点:canvas.getWidth()/2, 200
        canvas.drawCircle(startX, startY,  100, paint);  //画圆圈

//使用path绘制路径文字
        canvas.save();      //保存上面图层的信息
        canvas.translate(startX -  75, startY -  75);
        Path path =  new Path();
        path.addArc( new RectF( 00150150), - 145180);
        Paint citePaint =  new Paint(paint);
        citePaint.setTextSize( 14);
        citePaint.setStrokeWidth( 1);
        citePaint.setColor(Color.GRAY);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawTextOnPath( "my compass", path,  280, citePaint);
        canvas.restore();      //恢复保存的图层

        Paint tmpPaint =  new Paint(paint);  //小刻度画笔对象
        tmpPaint.setStrokeWidth( 1);

float  y = startY -  100;
int count =  60//总刻度数

for( int i =  0 ; i < count ; i++) {

if(i %  5 ==  0) {
                canvas.drawLine(0f, y, 0f, y - 12f, paint);
                canvas.drawText( String.valueOf( i /  5 ), -4f, y - 20f, tmpPaint);

            }  else {
                canvas.drawLine(0f, y, 0f, y - 5f, tmpPaint);
            }
            canvas.rotate( 360 / count, startX, startY);  //旋转画纸
        }

//绘制中心点
        tmpPaint.setStyle(Paint.Style.FILL);
        tmpPaint.setColor(Color.GRAY);
        tmpPaint.setStrokeWidth( 4);
        canvas.drawCircle(startX, startY,  7, tmpPaint);
        tmpPaint.setStyle(Paint.Style.FILL);
//绘制指针
        canvas.drawLine(startX, startY,  startX, startY -  65, paint);
        canvas.restore();
    }

public  void initPath(Canvas canvas, Paint pathPaint, Path path,
int pathStartX,  int pathStartY,  int length) {
int pathX = pathStartX;
int pathY = pathStartY;
int pathLength = ( int) Math.sqrt(Math.pow(length,  2) + Math.pow(length,  2));

//设置开始位置
        path.moveTo(pathX, pathY);
        pathX += ( int) (pathLength * Math.cos(Math.toRadians( 45)));
        pathY += ( int) (pathLength * Math.sin(Math.toRadians( 45)));
        path.lineTo(pathX, pathY);
//第二条线
        path.lineTo(pathStartX, pathY);
    }
}

Canvas 平移和形变
Canvas的平移和形变是画面的平移和形变,平衡和形变后会形成新的画布与之前的画面进行合并,并不影响原来的图像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    @Override
protected  void onDraw(Canvas canvas) {
super.onDraw(canvas);
        Paint paint =  new Paint();
        paint.setColor(Color.GREEN);
        paint.setStyle(Style.STROKE);
        paint.setStrokeWidth( 3);

//平移
        canvas.save();
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.translate( 2510);
        paint.setColor(Color.RED);
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.restore();

//旋转
        canvas.save();   //如果不保存最原始的数据,新的平移会以上次的平移为基础
        canvas.translate( 2300);
        paint.setColor(Color.GREEN);
        canvas.drawRect( new Rect( 1010100100), paint);     
        canvas.rotate( 30);
        paint.setColor(Color.RED);
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.rotate( 30);
        paint.setColor(Color.GRAY);
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.restore();

//扭曲
        canvas.save();  
        canvas.translate( 3600);
        paint.setColor(Color.GREEN);
        canvas.drawRect( new Rect( 1010100100), paint);
        paint.setColor(Color.RED);
        canvas.skew( 1.2f,  0);   //X轴倾斜,Y轴不变  
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.restore();

//缩放
        canvas.save();  
        canvas.translate( 6000);
        paint.setStyle(Style.FILL);
        paint.setColor(Color.GREEN);
        canvas.drawRect( new Rect( 1010100100), paint);
        paint.setColor(Color.RED);
        canvas.scale( 0.5f,  0.8f);   //所有坐标按比例缩小
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.restore();
    }

Canvas 图层的保存与恢复
Canvas的图层保存与恢复是以栈的结构进行保存。遵循都先入后出的原则。通过sava()函数来把当前图层压栈。restore()函数来出栈上一次入栈的图层。也可能通多次调用save()来多次保存图层。 restoreToCount()来恢复指定层数的图层。



saveFlags参数说明
1
2
3
4
5
6
7
8
9
10
11
12
/** 保存Matrix **/
public  static  final  int MATRIX_SAVE_FLAG = 0x01;
/** 保存Clip **/
public  static  final  int CLIP_SAVE_FLAG = 0x02;
/** 保存Alpha */
public  static  final  int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04;
/** 保存Color */
public  static  final  int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;
/** 保存整个Layer的Clip */
public  static  final  int CLIP_TO_LAYER_SAVE_FLAG = 0x10;
/** 保存所有,很少用 */
public  static  final  int ALL_SAVE_FLAG = 0x1F; 



saveLayerAlpha的使用


1
2
3
4
5
6
7
8
9
10
11
12
13
14
canvas.drawColor(Color.WHITE);

canvas.translate( 1010);

mPaint.setColor(Color.RED);
canvas.drawCircle( 757575, mPaint);
//保存指定区域图层,并修改其透明度
canvas.saveLayerAlpha( 00200200, 0x55, LAYER_FLAGS);
mPaint.setColor(Color.BLUE);
//设置整个图层的透明度。在这里和上面的效果一样,但是要在setColor后面
//      mPaint.setAlpha(70);   
canvas.drawCircle( 12512575, mPaint);

canvas.restore();

Canvas Region API总结
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//Region API Android4.4 2015年5月16日
/**构造方法*/
 
Region();                    //创建一个空的区域 
Region(Region region);       //拷贝一个region
Region(Rect r);              //根据Rect创建
Region( int left,  int top,  int right,  int bottom);  //创建一个矩形的区域

/*设置函数方法*/
void setEmpty();
boolean set(Region region);  //利用新的区域值来替换原来的区域
boolean set(Rect r);         //利用矩形所代表的区域替换原来的区域
boolean set( int left,  int top,  int right,  int bottom);  //根据矩形的两个点构造出矩形区域来替换原来的区域值
boolean setPath(Path path, Region clip);     //根据路径的区域与某区域的交集,构造出新区域     

//判断
boolean isEmpty();
boolean isRect();
boolean isComplex();

//返回边界
Rect getBounds();
boolean getBounds(Rect r);
Path getBoundaryPath();
boolean getBoundaryPath(Path path);

//判断是否相交
boolean contains( int x,  int y);      //是否有包含某点
boolean quickContains(Rect r);       //是否有包含矩区域
boolean quickContains( int left,  int top,  int right,   //根据两点是有否包含矩区域
boolean quickReject(Rect r);         //是否没包含矩形
boolean quickReject( int left,  int top,  int right,  int bottom);  //根据两点是否没包含矩区域
boolean quickReject(Region rgn);     //是否没和该矩阵相交

//平移和变换
void translate( int dx,  int dy);
void translate( int dx,  int dy, Region dst);
void scale( float scale);             //hide
void scale( float scale, Region dst); //hide

//组合
boolean union(Rect r);
boolean op(Rect r, Op op);
boolean op( int left,  int top,  int right,  int bottom, Op op);
boolean op(Region region, Op op);
boolean op(Rect rect, Region region, Op op);
boolean op(Region region1, Region region2, Op op);
//组合方式:假设用region1  去组合region2   
public enum Op {  
        DIFFERENCE( 0),  //最终区域为region1 与 region2不同的区域  
        INTERSECT( 1),  // 最终区域为region1 与 region2相交的区域  
        UNION( 2),       //最终区域为region1 与 region2组合一起的区域  
        XOR( 3),         //最终区域为region1 与 region2相交之外的区域  
        REVERSE_DIFFERENCE( 4),  //最终区域为region2 与 region1不同的区域  
        REPLACE( 5);  //最终区域为为region2的区域  
 } 
int describeContents();
void writeToParcel(Parcel p,  int flags);

Canvas Region用法示例
                              
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Override
protected  void onDraw(Canvas canvas) {
super.onDraw(canvas);

    Paint paint =  new Paint();
    paint.setColor(Color.RED);
    paint.setStyle(Style.STROKE);
    paint.setStrokeWidth( 2);
    Path path =  new Path();

//总的显示荡然无存
    RectF rectf =  new RectF( 5050200500);
    path.addOval(rectf, Direction.CCW);

    Region rgn =  new Region();
//会显示的区域
    rgn.setPath(path,  new Region( 5050300600));

    drawRegion(canvas, rgn, paint);
}

private  void drawRegion(Canvas canvas, Region rgn, Paint paint) {
//把要显示的图像能过一个矩形组合来显示,放大显示出来的图像会发觉由很多小的矩形组成
    RegionIterator iter =  new RegionIterator(rgn);
    Rect r =  new Rect();

while (iter.next(r)) {
        canvas.drawRect(r, paint);
    }
}



Canvas clip系列函数用法示例
clip意为剪切,其实我觉得在这里意思为选中更为贴切,因为只有选中的区域才会操作有效。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
public  class MyClipView  extends View {
     private Paint mPaint;
     private Path mPath;
    
     public MyClipView(Context context) {
         super(context);
        setFocusable(true);

        mPaint =  new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth( 6);
        mPaint.setTextSize( 16);
        mPaint.setTextAlign(Paint.Align.RIGHT);

        mPath =  new Path();
    }
    
     private  void drawScene(Canvas canvas) {
         //下面的画图只在已被剪切的范围内有效
       canvas.clipRect( 00100100);

        canvas.drawColor(Color.WHITE);

        mPaint.setColor(Color.RED);
        canvas.drawLine( 00100100, mPaint);

        mPaint.setColor(Color.GREEN);
        canvas.drawCircle( 307030, mPaint);

        mPaint.setColor(Color.BLUE);
        canvas.drawText( "Clipping"10030, mPaint);
    }

    @Override  protected  void onDraw(Canvas canvas) {
//        canvas.drawColor(Color.GRAY);
        
         //没有被多次剪切的情况
        canvas.save();
        canvas.translate( 1010);
        drawScene(canvas);
        canvas.restore();

        canvas.save();
        canvas.translate( 16010);
        canvas.clipRect( 10109090);
        canvas.clipRect( 30307070, Region.Op.DIFFERENCE);
        drawScene(canvas);
        canvas.restore();

        canvas.save();
        canvas.translate( 10160);
        mPath.reset();
        canvas.clipPath(mPath);  // makes the clip empty
        mPath.addCircle( 505050, Path.Direction.CCW);
        canvas.clipPath(mPath, Region.Op.REPLACE);
        drawScene(canvas);
        canvas.restore();

        canvas.save();
        canvas.translate( 160160);
        canvas.clipRect( 006060);
        canvas.clipRect( 4040100100, Region.Op.UNION);
        drawScene(canvas);
        canvas.restore();

        canvas.save();
        canvas.translate( 10310);
        canvas.clipRect( 006060);
        canvas.clipRect( 4040100100, Region.Op.INTERSECT);
        drawScene(canvas);
        canvas.restore();
        
        canvas.save();
        canvas.translate( 160310);
        canvas.clipRect( 006060);
        canvas.clipRect( 4040100100, Region.Op.XOR);
        drawScene(canvas);
        canvas.restore();
      
        canvas.save();
        canvas.translate( 10460);
        canvas.clipRect( 006060);
        canvas.clipRect( 4040100100, Region.Op.REVERSE_DIFFERENCE);
        drawScene(canvas);
        canvas.restore();       

    }
}


加入顶点 

参考文章:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//Canvas 操作函数 2015年5月15日 Android 4.4

int MATRIX_SAVE_FLAG = 0x01;
int CLIP_SAVE_FLAG = 0x02;
int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04;
int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;
int CLIP_TO_LAYER_SAVE_FLAG = 0x10;
int ALL_SAVE_FLAG = 0x1F; 
int DIRECTION_LTR =  0;

Canvas();
Canvas(Bitmap bitmap);

boolean isHardwareAccelerated();
void setBitmap(Bitmap bitmap);
boolean isOpaque();
int getWidth();
int getHeight();
int getDensity();
void setDensity( int density);
int getMaximumBitmapWidth();
int getMaximumBitmapHeight();

//图层保存与恢复操作
int save();    //保存当前图层
int save( int saveFlags);
//保存指定区域图层
//paint为要保存的画笔,restore()后可以用。一般为null
//saveFlags为要保存的内容
int saveLayer(RectF bounds, Paint paint,  int saveFlags);  
int saveLayer( float left,  float top,  float right,  float bottom, Paint paint,  int saveFlags);
//保存指定区域图层,并修改其透明度
int saveLayerAlpha(RectF bounds,  int alpha,  int saveFlags);
int saveLayerAlpha( float left,  float top,  float right,  float bottom,  int alpha,  int saveFlags);
void restore();          //恢复上一层图层
int getSaveCount();      //获得已只在的图层数量
void restoreToCount( int saveCount);   //恢复指定层的图层
//图层变换
void translate( float dx,  float dy);
void scale( float sx,  float sy);
void scale( float sx,  float sy,  float px,  float py);
void rotate( float degrees);
void rotate( float degrees,  float px,  float py);
void skew( float sx,  float sy);   //扭曲
void concat(Matrix matrix);   //Maxrix矩阵变换

void setMatrix(Matrix matrix);
void getMatrix(Matrix ctm);
Matrix getMatrix();
//裁剪
boolean clipRect(RectF rect, Region.Op op);
boolean clipRect(Rect rect, Region.Op op);
boolean clipRect(RectF rect);
boolean clipRect(Rect rect);
boolean clipRect( float left,  float top,  float right,  float bottom, Region.Op op);
boolean clipRect( float left,  float top,  float right,  float bottom);
boolean clipRect( int left,  int top,  int right,  int bottom);
boolean clipPath(Path path, Region.Op op);
boolean clipPath(Path path);
boolean clipRegion(Region region, Region.Op op);
boolean clipRegion(Region region);

DrawFilter getDrawFilter();
void setDrawFilter(DrawFilter filter);
boolean quickReject(RectF rect, EdgeType type);
boolean quickReject(Path path, EdgeType type);
boolean quickReject( float left,  float top,  float right,  float bottom, EdgeType type);
boolean getClipBounds(Rect bounds);
Rect getClipBounds();

//填充RGB
void drawRGB( int r,  int g,  int b);
void drawARGB( int a,  int r,  int g,  int b);
//填充Color
void drawColor( int color);
void drawColor( int color, PorterDuff.Mode mode);
//指定画笔
void drawPaint(Paint paint);
//画点
void drawPoints( float[] pts,  int offset,  int count, Paint paint);
void drawPoints( float[] pts, Paint paint);
void drawPoint( float x,  float y, Paint paint);
//画直线
void drawLine( float startX,  float startY,  float stopX,  float stopY, Paint paint);
void drawLines( float[] pts,  int offset,  int count, Paint paint);   //pts数组里的每两个元素为一个点,每两个点画一条直线
void drawLines( float[] pts, Paint paint);
//画矩形
void drawRect(RectF rect, Paint paint);
void drawRect(Rect r, Paint paint);
void drawRect( float left,  float top,  float right,  float bottom, Paint paint);
//画椭圆
void drawOval(RectF oval, Paint paint);
//画圆
void drawCircle( float cx,  float cy,  float radius, Paint paint);
//画弧,扇形
void drawArc(RectF oval,  float startAngle,  float sweepAngle,  boolean useCenter, Paint paint);
//画圆角矩形
void drawRoundRect(RectF rect,  float rx,  float ry, Paint paint);
//画路径
void drawPath(Path path, Paint paint);
//画位图
void drawBitmap(Bitmap bitmap,  float left,  float top, Paint paint);
void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint);
void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint);
void drawBitmap( int[] colors,  int offset,  int stride,  float x,  float y,  int width,  int height,  boolean hasAlpha,
void drawBitmap( int[] colors,  int offset,  int stride,  int x,  int y,  int width,  int height,  boolean hasAlpha, Paint paint);
void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint);
void drawBitmapMesh(Bitmap bitmap,  int meshWidth,  int meshHeight,  float[] verts,  int vertOffset,  int[] colors,  int colorOffset, Paint paint);
//画顶点
void drawVertices(VertexMode mode,  int vertexCount,  float[] verts,  int vertOffset,  float[] texs,  int texOffset,  int[] colors,  int colorOffset,  short[] indices,  int indexOffset,
//画字
void drawText( char[] text,  int index,  int count,  float x,  float y, Paint paint);
void drawText( String text,  float x,  float y, Paint paint);
void drawText( String text,  int start,  int end,  float x,  float y, Paint paint);
void drawText(CharSequence text,  int start,  int end,  float x,  float y, Paint paint);
//绝对值画字
void drawPosText( char[] text,  int index,  int count,  float[] pos, Paint paint);
void drawPosText( String text,  float[] pos, Paint paint);
//根据路径画字
void drawTextOnPath( char[] text,  int index,  int count, Path path,  float hOffset,  float vOffset, Paint paint);
void drawTextOnPath( String text, Path path,  float hOffset,  float vOffset, Paint paint);
//画图片
void drawPicture(Picture picture);
void drawPicture(Picture picture, RectF dst);
void drawPicture(Picture picture, Rect dst);

Canvas draw系列函数用法示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

public  class MyCanvasDrawView  extends View {

private  static  final  String TAG = null;

public MyCanvasDrawView(Context context) {
super(context);

    }

    @Override
protected  void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置背景颜色
        canvas.drawColor(Color.WHITE);
//画弧
        drawMultArc(canvas);
//画路径和文字
        drawPathWithText(canvas);
//画直线
        drawLine(canvas);
//sample
        drawCompass(canvas,  10400);
    }

public  void drawLine(Canvas canvas) {
        Paint paint =  new Paint();
        paint.setColor(Color.YELLOW);
        paint.setStrokeWidth( 5);
float offset =  150 /  6;
float leveOff =  150 /  4;
float[] pts = {600f + offset *  2, 400f - leveOff *  2, 750f - offset *  2, 400f - leveOff *  2,
                       600f + offset, 400f - leveOff , 750f - offset, 400f - leveOff,
                       600f, 400f , 750f, 400f
                      };
        canvas.drawLines(pts , paint);
    }

public  void drawMultArc(Canvas canvas) {
        Paint[] mPaints;
boolean[] mUseCenters;
        RectF[] mRectF;

//边框的画笔
        Paint rectPaint =  new Paint();
        rectPaint.setAntiAlias(true);
        rectPaint.setColor(Color.GRAY);
        rectPaint.setStyle(Paint.Style.STROKE);
        rectPaint.setStrokeWidth( 5);

        mUseCenters =  new  boolean[ 4];
        mPaints =  new Paint[ 4];
        mRectF =  new RectF[ 4];

        initDrawMultArc(mPaints, mUseCenters);

        _drawMultArc(canvas, mPaints, mUseCenters, mRectF, rectPaint);
    }

public  void initDrawMultArc(Paint[] mPaints,  boolean[] mUseCenters) {
//      1. 填充圆弧但不含圆心:
        mPaints[ 0] =  new Paint();
        mPaints[ 0].setAntiAlias(true);
        mPaints[ 0].setStyle(Paint.Style.FILL);
        mPaints[ 0].setColor(0x88FF0000);
        mUseCenters[ 0] = false;

//      2. 填充圆弧带圆心(扇形)
        mPaints[ 1] =  new Paint(mPaints[ 0]);
        mPaints[ 1].setColor(0x8800FF00);
        mUseCenters[ 1] = true;

//      3. 只绘圆周,不含圆心
        mPaints[ 2] =  new Paint(mPaints[ 0]);
        mPaints[ 2].setStyle(Paint.Style.STROKE);
        mPaints[ 2].setStrokeWidth( 4);
        mPaints[ 2].setColor(0x880000FF);
        mUseCenters[ 2] = false;

//      4. 只绘圆周,带圆心(扇形)
        mPaints[ 3] =  new Paint(mPaints[ 2]);
        mPaints[ 3].setColor(0x88888888);
        mUseCenters[ 3] = true;
    }

public  void _drawMultArc(Canvas canvas, Paint[] mPaints,
boolean[] mUseCenters, RectF[] mRectF, Paint rectPaint) {
int rectLeft =  10;
int rectTop =  50;
int width =  150;
int rectRight = rectLeft + width;
int rectBottom = rectTop + width;
int offest = rectLeft + width +  30 ;

//初始化弧形的区域,决定弧形的开关和位置
         for( int i =  0; i <  4; i++) {
            mRectF[i] =  new RectF(rectLeft + i * offest, rectTop, rectRight + i * offest, rectBottom);
        }

        Log.i(TAG,  "mRectF[3] " + mRectF[ 3].left +  " " + mRectF[ 3].bottom);

/**
         * 参数1:弧形的区域
         * 参数2:起始的角度
         * 参数3:弧形的角度
         * 参数4:是否有中心角度
         */

for (  int i =  0; i <  4; i++ ) {
            canvas.drawArc(mRectF[i],  30260, mUseCenters[i], mPaints[i]);
            canvas.drawRect(mRectF[i], rectPaint);
        }
    }

public  void drawPathWithText(Canvas canvas) {
        Paint pathPaint =  new Paint();
        pathPaint.setARGB( 7023818137);
        pathPaint.setStyle(Paint.Style.FILL);
        pathPaint.setAntiAlias(true);
        pathPaint.setStrokeWidth( 5);

        Path path =  new Path();

int pathStartX =  10;
int pathStartY =  250;
int length =  150;
//第一个三角形
        initPath(canvas, pathPaint, path, pathStartX, pathStartY, length);
        canvas.drawPath(path , pathPaint);

//清除path属性
        path.reset();
        pathPaint.setColor(Color.CYAN);
        pathPaint.setStyle(Paint.Style.STROKE);
        pathStartX = length +  50;
//第二个三角形
        initPath(canvas, pathPaint, path, pathStartX, pathStartY, length);
        canvas.drawPath(path , pathPaint);

//第三个图形
        path.reset();
        pathPaint.setColor(Color.DKGRAY);
        pathStartX = (length +  50) *  2;
//逆时针添加一个圆
         //最后一个参数指定构建方法,逆时针和顺时针,并不影响图形效果,但是会影响文字的构建顺序
        path.addCircle(pathStartX +  length /  2 , pathStartY +  length /  2, length /  2, Path.Direction.CCW);
        canvas.drawPath(path , pathPaint);

//设置字体属性
        pathPaint.setStrokeWidth( 1);
        pathPaint.setTextSize( 30);
        pathPaint.setTypeface(Typeface.SERIF);
        canvas.drawTextOnPath( "Android Canvas&Paint", path,  1028, pathPaint);
        pathPaint.setTextSize( 25);
        pathPaint.setStyle(Paint.Style.FILL);
        canvas.drawTextOnPath( "Android", path,  10, - 10, pathPaint);
    }

public  void drawCompass(Canvas canvas,  int startX,  int startY) {

        canvas.save();
        Paint paint;
        paint =  new Paint();  //设置一个笔刷大小是3的黄色的画笔
        paint.setColor(Color.BLACK);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeWidth( 3);

        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        canvas.translate(canvas.getWidth() /  2200);  //移动画纸的坐标点:canvas.getWidth()/2, 200
        canvas.drawCircle(startX, startY,  100, paint);  //画圆圈

//使用path绘制路径文字
        canvas.save();      //保存上面图层的信息
        canvas.translate(startX -  75, startY -  75);
        Path path =  new Path();
        path.addArc( new RectF( 00150150), - 145180);
        Paint citePaint =  new Paint(paint);
        citePaint.setTextSize( 14);
        citePaint.setStrokeWidth( 1);
        citePaint.setColor(Color.GRAY);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawTextOnPath( "my compass", path,  280, citePaint);
        canvas.restore();      //恢复保存的图层

        Paint tmpPaint =  new Paint(paint);  //小刻度画笔对象
        tmpPaint.setStrokeWidth( 1);

float  y = startY -  100;
int count =  60//总刻度数

for( int i =  0 ; i < count ; i++) {

if(i %  5 ==  0) {
                canvas.drawLine(0f, y, 0f, y - 12f, paint);
                canvas.drawText( String.valueOf( i /  5 ), -4f, y - 20f, tmpPaint);

            }  else {
                canvas.drawLine(0f, y, 0f, y - 5f, tmpPaint);
            }
            canvas.rotate( 360 / count, startX, startY);  //旋转画纸
        }

//绘制中心点
        tmpPaint.setStyle(Paint.Style.FILL);
        tmpPaint.setColor(Color.GRAY);
        tmpPaint.setStrokeWidth( 4);
        canvas.drawCircle(startX, startY,  7, tmpPaint);
        tmpPaint.setStyle(Paint.Style.FILL);
//绘制指针
        canvas.drawLine(startX, startY,  startX, startY -  65, paint);
        canvas.restore();
    }

public  void initPath(Canvas canvas, Paint pathPaint, Path path,
int pathStartX,  int pathStartY,  int length) {
int pathX = pathStartX;
int pathY = pathStartY;
int pathLength = ( int) Math.sqrt(Math.pow(length,  2) + Math.pow(length,  2));

//设置开始位置
        path.moveTo(pathX, pathY);
        pathX += ( int) (pathLength * Math.cos(Math.toRadians( 45)));
        pathY += ( int) (pathLength * Math.sin(Math.toRadians( 45)));
        path.lineTo(pathX, pathY);
//第二条线
        path.lineTo(pathStartX, pathY);
    }
}

Canvas 平移和形变
Canvas的平移和形变是画面的平移和形变,平衡和形变后会形成新的画布与之前的画面进行合并,并不影响原来的图像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    @Override
protected  void onDraw(Canvas canvas) {
super.onDraw(canvas);
        Paint paint =  new Paint();
        paint.setColor(Color.GREEN);
        paint.setStyle(Style.STROKE);
        paint.setStrokeWidth( 3);

//平移
        canvas.save();
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.translate( 2510);
        paint.setColor(Color.RED);
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.restore();

//旋转
        canvas.save();   //如果不保存最原始的数据,新的平移会以上次的平移为基础
        canvas.translate( 2300);
        paint.setColor(Color.GREEN);
        canvas.drawRect( new Rect( 1010100100), paint);     
        canvas.rotate( 30);
        paint.setColor(Color.RED);
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.rotate( 30);
        paint.setColor(Color.GRAY);
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.restore();

//扭曲
        canvas.save();  
        canvas.translate( 3600);
        paint.setColor(Color.GREEN);
        canvas.drawRect( new Rect( 1010100100), paint);
        paint.setColor(Color.RED);
        canvas.skew( 1.2f,  0);   //X轴倾斜,Y轴不变  
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.restore();

//缩放
        canvas.save();  
        canvas.translate( 6000);
        paint.setStyle(Style.FILL);
        paint.setColor(Color.GREEN);
        canvas.drawRect( new Rect( 1010100100), paint);
        paint.setColor(Color.RED);
        canvas.scale( 0.5f,  0.8f);   //所有坐标按比例缩小
        canvas.drawRect( new Rect( 1010100100), paint);
        canvas.restore();
    }

Canvas 图层的保存与恢复、
Canvas的图层保存与恢复是以栈的结构进行保存。遵循都先入后出的原则。通过sava()函数来把当前图层压栈。restore()函数来出栈上一次入栈的图层。也可能通多次调用save()来多次保存图层。 restoreToCount()来恢复指定层数的图层。


saveFlags参数说明
1
2
3
4
5
6
7
8
9
10
11
12
/** 保存Matrix **/
public  static  final  int MATRIX_SAVE_FLAG = 0x01;
/** 保存Clip **/
public  static  final  int CLIP_SAVE_FLAG = 0x02;
/** 保存Alpha */
public  static  final  int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04;
/** 保存Color */
public  static  final  int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;
/** 保存整个Layer的Clip */
public  static  final  int CLIP_TO_LAYER_SAVE_FLAG = 0x10;
/** 保存所有,很少用 */
public  static  final  int ALL_SAVE_FLAG = 0x1F; 



saveLayerAlpha的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
canvas.drawColor(Color.WHITE);

canvas.translate( 1010);

mPaint.setColor(Color.RED);
canvas.drawCircle( 757575, mPaint);
//保存指定区域图层,并修改其透明度
canvas.saveLayerAlpha( 00200200, 0x55, LAYER_FLAGS);
mPaint.setColor(Color.BLUE);
//设置整个图层的透明度。在这里和上面的效果一样,但是要在setColor后面
//      mPaint.setAlpha(70);   
canvas.drawCircle( 12512575, mPaint);

canvas.restore();

Canvas Region API总结
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//Region API Android4.4 2015年5月16日
/**构造方法*/
 
Region();                    //创建一个空的区域 
Region(Region region);       //拷贝一个region
Region(Rect r);              //根据Rect创建
Region( int left,  int top,  int right,  int bottom);  //创建一个矩形的区域

/*设置函数方法*/
void setEmpty();
boolean set(Region region);  //利用新的区域值来替换原来的区域
boolean set(Rect r);         //利用矩形所代表的区域替换原来的区域
boolean set( int left,  int top,  int right,  int bottom);  //根据矩形的两个点构造出矩形区域来替换原来的区域值
boolean setPath(Path path, Region clip);     //根据路径的区域与某区域的交集,构造出新区域     

//判断
boolean isEmpty();
boolean isRect();
boolean isComplex();

//返回边界
Rect getBounds();
boolean getBounds(Rect r);
Path getBoundaryPath();
boolean getBoundaryPath(Path path);

//判断是否相交
boolean contains( int x,  int y);      //是否有包含某点
boolean quickContains(Rect r);       //是否有包含矩区域
boolean quickContains( int left,  int top,  int right,   //根据两点是有否包含矩区域
boolean quickReject(Rect r);         //是否没包含矩形
boolean quickReject( int left,  int top,  int right,  int bottom);  //根据两点是否没包含矩区域
boolean quickReject(Region rgn);     //是否没和该矩阵相交

//平移和变换
void translate( int dx,  int dy);
void translate( int dx,  int dy, Region dst);
void scale( float scale);             //hide
void scale( float scale, Region dst); //hide

//组合
boolean union(Rect r);
boolean op(Rect r, Op op);
boolean op( int left,  int top,  int right,  int bottom, Op op);
boolean op(Region region, Op op);
boolean op(Rect rect, Region region, Op op);
boolean op(Region region1, Region region2, Op op);
//组合方式:假设用region1  去组合region2   
public enum Op {  
        DIFFERENCE( 0),  //最终区域为region1 与 region2不同的区域  
        INTERSECT( 1),  // 最终区域为region1 与 region2相交的区域  
        UNION( 2),       //最终区域为region1 与 region2组合一起的区域  
        XOR( 3),         //最终区域为region1 与 region2相交之外的区域  
        REVERSE_DIFFERENCE( 4),  //最终区域为region2 与 region1不同的区域  
        REPLACE( 5);  //最终区域为为region2的区域  
 } 
int describeContents();
void writeToParcel(Parcel p,  int flags);

Canvas Region用法示例
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Override
protected  void onDraw(Canvas canvas) {
super.onDraw(canvas);

    Paint paint =  new Paint();
    paint.setColor(Color.RED);
    paint.setStyle(Style.STROKE);
    paint.setStrokeWidth( 2);
    Path path =  new Path();

//总的显示荡然无存
    RectF rectf =  new RectF( 5050200500);
    path.addOval(rectf, Direction.CCW);

    Region rgn =  new Region();
//会显示的区域
    rgn.setPath(path,  new Region( 5050300600));

    drawRegion(canvas, rgn, paint);
}

private  void drawRegion(Canvas canvas, Region rgn, Paint paint) {
//把要显示的图像能过一个矩形组合来显示,放大显示出来的图像会发觉由很多小的矩形组成
    RegionIterator iter =  new RegionIterator(rgn);
    Rect r =  new Rect();

while (iter.next(r)) {
        canvas.drawRect(r, paint);
    }
}



Canvas clip系列函数用法示例
clip意为剪切,其实我觉得在这里意思为选中更为贴切,因为只有选中的区域才会操作有效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
public  class MyClipView  extends View {
     private Paint mPaint;
     private Path mPath;
    
     public MyClipView(Context context) {
         super(context);
        setFocusable(true);

        mPaint =  new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth( 6);
        mPaint.setTextSize( 16);
        mPaint.setTextAlign(Paint.Align.RIGHT);

        mPath =  new Path();
    }
    
     private  void drawScene(Canvas canvas) {
         //下面的画图只在已被剪切的范围内有效
       canvas.clipRect( 00100100);

        canvas.drawColor(Color.WHITE);

        mPaint.setColor(Color.RED);
        canvas.drawLine( 00100100, mPaint);

        mPaint.setColor(Color.GREEN);
        canvas.drawCircle( 307030, mPaint);

        mPaint.setColor(Color.BLUE);
        canvas.drawText( "Clipping"10030, mPaint);
    }

    @Override  protected  void onDraw(Canvas canvas) {
//        canvas.drawColor(Color.GRAY);
        
         //没有被多次剪切的情况
        canvas.save();
        canvas.translate( 1010);
        drawScene(canvas);
        canvas.restore();

        canvas.save();
        canvas.translate( 16010);
        canvas.clipRect( 10109090);
        canvas.clipRect( 30307070, Region.Op.DIFFERENCE);
        drawScene(canvas);
        canvas.restore();

        canvas.save();
        canvas.translate( 10160);
        mPath.reset();
        canvas.clipPath(mPath);  // makes the clip empty
        mPath.addCircle( 505050, Path.Direction.CCW);
        canvas.clipPath(mPath, Region.Op.REPLACE);
        drawScene(canvas);
        canvas.restore();

        canvas.save();
        canvas.translate( 160160);
        canvas.clipRect( 006060);
        canvas.clipRect( 4040100100, Region.Op.UNION);
        drawScene(canvas);
        canvas.restore();

        canvas.save();
        canvas.translate( 10310);
        canvas.clipRect( 006060);
        canvas.clipRect( 4040100100, Region.Op.INTERSECT);
        drawScene(canvas);
        canvas.restore();
        
        canvas.save();
        canvas.translate( 160310);
        canvas.clipRect( 006060);
        canvas.clipRect( 4040100100, Region.Op.XOR);
        drawScene(canvas);
        canvas.restore();
      
        canvas.save();
        canvas.translate( 10460);
        canvas.clipRect( 006060);
        canvas.clipRect( 4040100100, Region.Op.REVERSE_DIFFERENCE);
        drawScene(canvas);
        canvas.restore();       

    }
}


加入顶点 

参考文章:

猜你喜欢

转载自blog.csdn.net/shell812/article/details/49783487