Canvas&Paint[]Canvas:draw

【参考链接】

自定义控件之绘图篇http://blog.csdn.net/harvic880925/article/details/38875149

 

画布用于控制形状。

要画图,必须要先创建一个画布

画布Canvas的创建需要传递一个Bitmap对象,并且这个Bitmap得是可修改的,即需要来自Bitmap.createBitmap(),而不能来自BitmapFactory.decode()

Bitmap bmp=Bitmap.createBitmap(800, 800, Bitmap.Config.ARGB_8888);
Canvas canvas=new Canvas(bmp);
canvas.drawColor(Color.parseColor("#FF0000"));

ImageView iv =(ImageView) findViewById(R.id.iv);
iv.setImageBitmap(bmp);

创建画布的时候还需要指定大小,当绘制元素位于画布以外时,自然也不会绘制出来。

 

在进行绘图之前,需要先了解画布的坐标系

下面的画图函数中,所指定的坐标,都是相对于画布坐标系的坐标。

初始情况下,画布坐标系的原点在画布的左上角,但是也可以移动/旋转/缩放画布坐标系。


 

Canvas对象提供了很多方法来画图,在画图之前,需要先指定画笔。

Paint对象来描述一个画笔,下面使用的画笔样式如下

//默认画笔
Paint paintAll=new Paint();
paintAll.setAlpha(255);//不透明度//完全不透明
paintAll.setAntiAlias(true);
paintAll.setColor(Color.parseColor("#000000"));//黑色//默认就是黑色

paintAll.setStyle(Paint.Style.STROKE);
paintAll.setStrokeWidth(2);

后续会改变画笔的样式来了解不同样式对绘画元素的影响

 

下面代码的各种绘画的效果如下


 

1.       

drawPointdrawLine可以看作一类

drawPoint(float x, float y, Paint paint)

在位置(x, y)绘制一个点

canvas.drawPoint(x, y, paintAll);

 

drawLine(float startX, float startY, float stopX, floatstopY, Paint paint)

canvas.drawLine(x, y, x+200, y, paintAll);

 

2.       

drawRectdrawRoundRectdrawCircledrawOvaldrawArc可以看作一类

drawRect(float left, float top, float right, float bottom,Paint paint)

canvas.drawRect(x, y, x+200, y+200, paintAll);

 

drawRoundRect(RectF rect, float rx, float ry, Paint paint)

canvas.drawRoundRect(x, y, x+200, y+200, 20, 40, paintAll);

 

drawCircle(float cx, float cy, float radius, Paint paint)

canvas.drawCircle(x+100, y+100, 100, paintAll);

 

drawOval(float left, float top, float right, float bottom,Paint paint)

(left,top, right, bottom)所表示的矩形的内切圆

canvas.drawOval(x, y, x+200, y+200, paintAll);

 

drawArc(float left, float top, float right, float bottom,float startAngle, float sweepAngle, boolean useCenter, Paint paint)

矩形的内切圆的一段弧,从startAngle角度开始,划过sweepAngle角度

userCenter=true表示画扇形,userCenter=false表示画弧形

 

canvas.drawArc(x, y, x+200, y+200, 90, 90, true, paintAll);//useCenter=true

canvas.drawArc(x, y, x+200, y+200, 0, 90, false, paintAll);//useCenter=false

 

3.       

drawPath(Path path, Paint paint)

画一段路径

path既可以来自添加点moveTo()lineTo()quadTo()close()

也可以来自添加其他图形addRect()addRoundRect()addCircle()addOval()addArc(),添加其他图形是还需要设置方向。并且,不同的图形,起始点也不同。方向和起始点会影响后面的drawTextOnPath().

Path path = new Path();
path.moveTo(x, y);
for
(int i = x; i <= 30; i++) {
    path.lineTo(i *
10, (float) (Math.random() * 100)+y);
}
path.close()
;
canvas.drawPath(path, paintAll);

 

path.reset();
RectF rect=new RectF(x, y, x+200, y+200);
//还可以添加不同的形状
path.addRect(rect, Path.Direction.CW);//顺时针
//
不同的形状,起始点也不同
canvas.drawPath(path, paintAll);

 

4.       

drawRegion

Region表示一块区域

可以通过一个Rect创建一块区域,也可以通过一个Path创建一块区域

//Rect创建一个Region
Rect rect1=new Rect(x, y+200, x+400, y+300);
Region region1=new Region(rect1);

 

//Path创建一个Region
Rect rect2=new Rect(x+200, y, x+300, y+400);
Path path2=new Path();
path2.addOval(new RectF(rect2), Path.Direction.CW);//这个Region是个椭圆
Region region2=new Region();
region2.setPath(path2, new Region(rect2));//第二个参数需要传递一个Rect,取Path和这个Rect的交集

 

多块区域之间可以通过op()函数进行取交集、取并集等操作

//取两个Region的并集
region1.op(region2, Region.Op.UNION);

 

借助RegionIterator类和drawRect()函数来绘制区域

RegionIterator iter= new RegionIterator(region1);
Rect rect3 = new Rect();
while
(iter.next(rect3)){
    canvas.drawRect(rect3
, paintAll);
}

 

 

5.       

drawText(String text, float x, float y, Paint paint)

paintAll.setTextSize(50);
canvas.drawText("HelloWorld", x, y, paintAll);

drawTextOnPath(String text, Path path, float hOffset,float vOffset, Paint paint)

还可以沿路径绘制文字,不过好像效果有点着急

hOffset影响文字对路径的贴近程度(如下图蓝色),vOffset影响文字的起始点的偏移(如下图红色)


 

path.reset();
rect=new RectF(x, y, x+200, y+200);
canvas.drawRect(rect, paintAll);
path.addRect(rect, Path.Direction.CW);//顺时针
canvas.drawTextOnPath("HelloWorld", path, 0, 0, paintAll);

x+=400;
path.reset();
rect=new RectF(x, y, x+200, y+200);
canvas.drawRect(rect, paintAll);
path.addRect(rect, Path.Direction.CW);//顺时针
canvas.drawTextOnPath("HelloWorld", path, 30, 30, paintAll);

x+=400;
path.reset();
canvas.drawCircle(x+100, y+100,100, paintAll);
path.addCircle(x+100, y+100,100, Path.Direction.CCW);//逆时针
canvas.drawTextOnPath("HelloWorld", path, 0, 0, paintAll);

x+=400;
path.reset();
canvas.drawCircle(x+100, y+100,100, paintAll);
path.addCircle(x+100, y+100,100, Path.Direction.CCW);//逆时针
canvas.drawTextOnPath("HelloWorld", path, 30, 30, paintAll);

 

6.       

drawBitmap(Bitmap bitmap, float left, float top, Paintpaint)

(lefttop)上绘制一张与原图大小相同的图片

Bitmap bmp2=BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
canvas.drawBitmap(bmp2, x, y, paintAll);

 

drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)

将原图的src区域取出来,画到画布坐标系的dst区域去

canvas.drawBitmap(bmp2,
       new
Rect(0, 0, bmp2.getWidth(), bmp2.getHeight()),
       new
Rect(x, y, x+200, y+200),
       
paintAll);

 

drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)

还可以结合Matrix

使用Matrix的时候,不用指定要绘制到的左上角的坐标,是因为其原理为

假设原图的左上角位于画布坐标系的原点,对于原图上的每一点,应用Matrix变换,将其画到画布上去

当然,在Matrix中也讲过,如果Matrix中有多次变换,是计算出结果来以后只进行一次绘图,所以可能translate()rotate()的效果并不是先平移再旋转。

所以也不建议使用多次变换,如果需要实现这种效果可以考虑操作画布坐标系。

       Matrix matrix=new Matrix();
       
matrix.setTranslate(x, y);
       
printMatrix(matrix);
//       canvas.save();
//       canvas.translate(200, 200);
       
canvas.drawBitmap(bmp2, matrix, paintAll);
//       canvas.restore();

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值