赞
踩
【参考链接】
自定义控件之绘图篇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);
后续会改变画笔的样式来了解不同样式对绘画元素的影响
下面代码的各种绘画的效果如下
drawPoint、drawLine可以看作一类
在位置(x, y)绘制一个点
canvas.drawPoint(x, y, paintAll);
canvas.drawLine(x, y, x+200, y, paintAll);
drawRect、drawRoundRect、drawCircle、drawOval、drawArc可以看作一类
canvas.drawRect(x, y, x+200, y+200, paintAll);
canvas.drawRoundRect(x, y, x+200, y+200, 20, 40, paintAll);
canvas.drawCircle(x+100, y+100, 100, paintAll);
(left,top, right, bottom)所表示的矩形的内切圆
canvas.drawOval(x, y, x+200, y+200, paintAll);
矩形的内切圆的一段弧,从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
画一段路径
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);
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);
}
paintAll.setTextSize(50);
canvas.drawText("HelloWorld", x, y, paintAll);
还可以沿路径绘制文字,不过好像效果有点着急
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);
在(left、top)上绘制一张与原图大小相同的图片
Bitmap bmp2=BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
canvas.drawBitmap(bmp2, x, y, paintAll);
将原图的src区域取出来,画到画布坐标系的dst区域去
canvas.drawBitmap(bmp2,
new Rect(0, 0, bmp2.getWidth(), bmp2.getHeight()),
new Rect(x, y, x+200, y+200),
paintAll);
还可以结合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();
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。