一个画图需要四大基本要素: 1、一个用来保存像素的Bitmap; 2、一个Canvas画布,绘制Bitmap操作; 3、绘制的东西 4、绘制的画笔Paint(颜色和样式)
Canvas大致可以分为三类方法: 1. save、restore 等与层的保存和回滚相关的方法; 2. scale、rotate、clipXXX 等对画布进行操作的方法; 3. drawXXX 等一系列绘画相关的方法;
如何获得一个Canvas对象。 Canvas对象的获取方式有三种: 第一种我们通过重写View.onDraw方法,View中的Canvas对象会被当做参数传递过来,我们操作这个Canvas,效果会直接反应在View中。 第二种就是当你想自己创建一个Canvas对象。从上面的基本要素可以明白,一个Canvas对象一定是结合了一个Bitmap对象的。所以一定要为一个Canvas对象设置一个Bitmap对象。
//得到一个Bitmap对象,当然也可以使用别的方式得到。但是要注意,改bitmap一定要是mutable(异变的) Bitmap b = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); /*先new一个Canvas对象,在调用setBitmap方法,一样的效果 * Canvas c = new Canvas(); * c.setBitmap(b); */第三种方式,是调用SurfaceHolder.lockCanvas(),返回一个Canvas对象。
1.Canvas 的左上角是(0,0); 2.基于左上角往右 X 为正,往下 Y 为正,反之为负; 3.移动单位为px
canvas和显示没关系,只影响画图的坐标系。画布的平移旋转等操作,可以视为坐标系的操作。
//平移public void translate(float dx, float dy) {//画布移动x、y的距离}//缩放public void scale(float sx, float sy) {//画布x、y方向缩放倍率,使用默认基准点(原点 0,0)} public final void scale(float sx, float sy, float px, float py) {//画布x、y方向缩放倍率,使用基准点(px,py)}//旋转 public void rotate(float degrees) {//画布旋转角度,旋转中心:画布原点(0,0)}public final void rotate(float degrees, float px, float py) {//画布旋转角度,旋转中心坐标(px,py)}蓝色的是手机屏幕边框,红色的是一个全屏的canvas
当canvas旋转30度之后,其实成了这个样子,但是你绘制的图形还是只能在canvas内,并且坐标是按照canvas旋转之前来的,也就是左上角坐标仍然是(0,0),右下角的坐标仍然是(width,height)。图片永远画在canvas中的,图片相对于canvas是没有任何变化的。
1)填充 drawARGB(int a, int r, int g, int b) drawColor(int color) drawRGB(int r, int g, int b) drawColor(int color, PorterDuff.Mode mode) 2)几何图形
//弧,扇形public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint) {//弧所在矩形,起始角度,扫过角度(正方形:顺时针),是否使用中心,画笔}public void drawArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean useCenter, @NonNull Paint paint) {//弧所在矩形的左上右下坐标,起始角度,扫过角度(正方形:顺时针),是否使用中心,画笔}//圆public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {//圆心坐标,半径,画笔}//椭圆 public void drawOval(@NonNull RectF oval, @NonNull Paint paint) {//椭圆所在矩形,画笔}public void drawOval(float left, float top, float right, float bottom, @NonNull Paint paint) {//椭圆所在矩形左上角右下角坐标,画笔}//点public void drawPoint(float x, float y, @NonNull Paint paint) {//点的xy,画笔}//矩形public void drawRect(@NonNull Rect r, @NonNull Paint paint) {//矩形,画笔}public void drawRect(@NonNull RectF rect, @NonNull Paint paint) {//矩形(坐标为浮点型),画笔}public void drawRect(float left, float top, float right, float bottom, @NonNull Paint paint) {//矩形左上右下坐标,画笔}//圆角矩形public void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {//圆角矩形所在矩形,x方向圆角半径,y方向圆角半径,画笔}public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, @NonNull Paint paint) {//圆角矩形所在矩形的左上右下坐标,x方向圆角半径,y方向圆角半径,画笔}//线public void drawLine(float startX, float startY, float stopX, float stopY,@NonNull Paint paint) {//线:起点坐标,终点坐标,画笔}3)图片 canvas.drawBitmap (位图) canvas.drawPicture (图片) 4)文本
public void drawText(@NonNull CharSequence text, int start, int end, float x, float y,@NonNull Paint paint) {//文本,文本的截取(start,end),(x,y)默认文本的左下角,若设置mTextPaint.setTextAlign(Paint.Align.CENTER);则为文本的水平中心位置,画笔}public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {//文本,(x,y)默认文本的左下角,若设置mTextPaint.setTextAlign(Paint.Align.CENTER);则为文本的水平中心位置,画笔}5、path
public void drawPath(@NonNull Path path, @NonNull Paint paint) {//path,画笔}在save到restore之间所画的图的操作,restore之后的代码不受影响 。 save保存画布,让后续操作类似在新的图层上操作一样,restore类似合并图层,让save前的图层与save后的图层合并。
reset() 重置画笔 setColor(int color) 给画笔设置颜色值 setARGB(int a, int r, int g, int b) 同样是设置颜色,但是利用ARGB分开设置 setAlpha(int a) 设置画笔透明度 setStyle(Paint.Style style) 设置画笔样式,取值有 Paint.Style.FILL :填充内部 Paint.Style.FILL_AND_STROKE :填充内部和描边 Paint.Style.STROKE :仅描边 setStrokeWidth(float width) 设置画笔宽度 setAntiAlias(boolean aa) 设置画笔是否抗锯齿 左边无抗锯齿,右边抗锯齿 setDither() 该方法是设置防抖动。 无防抖 有防抖 setStrokeCap(Paint.Cap cap) 设置线帽样式,取值有 Cap.ROUND(圆形线帽)、 Cap.SQUARE(方形线帽)、 Paint.Cap.BUTT(无线帽)
setStrokeJoin(Paint.Join join) 设置线段连接处样式,参数取值有: Join.MITER(结合处为锐角) Join.Round(结合处为圆弧) Join.BEVEL(结合处为直线)
setShader(Shader shader) 设置渐变效果 设置图像效果,使用Shader可以绘制出各种渐变效果; Shader下面有五个子类可用: BitmapShader :位图图像渲染 LinearGradient:线性渲染 RadialGradient:环形渲染 SweepGradient:扫描渐变渲染/梯度渲染 ComposeGradient:组合渲染,可以和其他几个子类组合起来使用 这几个类中LinearGradient、RadialGradient、SweepGradient均是可以将颜色进行处理,形成柔和的过渡,也可以称为渐变,而BitmapShader 则是直接使用位图进行渲染,就类似于贴图,在贴图的过程中根据需要自然就可以选择相应的模式,有三种模式可供选择,分别是: 枚举: emun Shader.TileMode 定义了平铺的3种模式: static final Shader.TileMode CLAMP: 边缘拉伸,即使用边缘的最后一个像素进行延展; static final Shader.TileMode MIRROR:在水平方向和垂直方向交替景象, 两个相邻图像间没有缝隙,从名称上看就像照镜子一样; Static final Shader.TillMode REPETA:在水平方向和垂直方向重复摆放,两个相邻图像间有缝隙缝隙;
setShadowLayer(float radius ,float dx,float dy,int color) 在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
setColorFilter(ColorFilter filter) 设置颜色过滤器,可以通过颜色过滤器过滤掉对应的色值,比如去掉照片颜色,生成老照片效果;
setPathEffect(PathEffect effect); //设置绘制路径的效果,如点画线等,给path设置样式(效果)
Canvas沿着路径绘制图形,我们可以这样来定义一条路径:(1)构造一个Path对象;(2)调用Path的moveTo(x,y)方法设定路径的起点;(3)调用lineTo(x,y)方法设定下一个点的位置。 (1)设置Path路径效果:首先需要创建一个PathEffect子类对象,然后再调用Paint的setPathEffect(PathEffect p)方法即可。 (2)沿着路径绘制文本:首先需要设定路径的形状,然后设置好画笔并调用Canvas的drawPath(Path path,Paint paint)方法沿着路径绘制图形,最后调用Canvas的drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)方法绘制路径文本,其中hOffset为相对于路径起点距离的水平位置,hOffset为相对于路径上或下距离。
moveTo(x,y): 不会进行绘制,只用于移动移动画笔,确定起点坐标,与其他方法配合使用; lineTo(x,y): 一阶贝塞尔曲线,坐标为终点坐标,配合moveTo方法用于进行直线绘制; quadTo (x1,y1,x2,y2): 二阶贝塞尔曲线,(x1,y1) 为控制点,(x2,y2)为结束点,用于绘制圆滑的曲线; cubicTo(x1, y1, x2, y2, x3, y3): 三阶贝塞尔曲线, (x1,y1) 为控制点,(x2,y2)为控制点,(x3,y3) 为结束点,用于绘制复杂的曲线。
参考
自定义控件三部曲之绘图篇(七)——Paint之函数大汇总
Paint、Canvas、Matrix使用讲解(一、Paint)
Android笔记二十八.Android绘图深度解析
新闻热点
疑难解答