Android Paint,Canvas api 详解

本文详细介绍了Android中的Paint和Canvas API。Paint主要用于设置画笔属性,如颜色、不透明度、抗锯齿等;Canvas则提供画布上的变换操作,如平移、缩放、旋转和错切。文章还通过实例展示了如何使用这两个类进行图形绘制,包括文字、圆形、线条、弧度、矩形等,并讨论了Canvas的状态保存和还原机制。

概述

我们通过在画布上绘画进行类比,如下:

Canvas:相当于画布,Bitmap提供内存,绘的画会保存在Bitmap中。
Paint:相当于画笔。

有了画笔和画笔我们就可以绘画了。

Paint 类常用方法

设置颜色

/**
 * 参数一:Android内部定义的有Color类包含了一些常见颜色定义
 * Color.RED 或者 getResources().getColor(android.R.color.holo_blue_bright)
 * 或者Color.rgb(255,100,100)或者Color.argb(50,255,100,100)
 */
paint.setColor(int color)  // 设置颜色
/**
 * 参数一:alpha透明值
 */
paint.setARGB(int a, int r, int g, int b) // 设置 Paint对象颜色

设置不透明度

paint.setAlpha(int a) // 设置alpha不透明度,范围为0~255

设置是否抗锯齿

paint.setAntiAlias(boolean aa) // 是否抗锯齿

设置文本缩放倍数

/**
 * 参数一:,1.0f为原始
 */
paint.setTextScaleX(float scaleX)  // 设置文本缩放倍数

设置字体大小

paint.setTextSize(float textSize)  // 设置字体大小

设置下划线

paint.setUnderlineText(booleanunderlineText)  // 设置下划线

设置实心还是空心

/**
 * 实心
 * /
paint.setStyle(Paint.Style.FILL);
/**
 * 空心
 * /
paint.setStyle(Paint.Style.STROKE);

设置画笔的粗细

paint.setStrokeWidth(10);

关键点:以上Paint的操作作用在下次绘画的画笔上

Canvas 常用方法

Canvas平移、缩放、旋转、画布的错切

关键点:Canvas平移、缩放、旋转操作作用在下次绘画的画布上

Canvas平移

/** 
 * 画布向(100,50)方向平移 
 *  
 * 参数1: 向X轴方向移动100距离 
 * 参数2: 向Y轴方向移动50距离   
 */
 canvas.translate(100, 50);

Canvas缩放

/** 
 * 在X轴方向放大为原来2倍,Y轴方向方大为原来的4倍 
 * 参数1: X轴的放大倍数 
 * 参数2: Y轴的放大倍数 
 */ 
canvas.scale(2, 4); 
/** 
 * 在X轴方向放大为原来2倍,Y轴方向方大为原来的4倍 
 * 参数1: X轴的放大倍数
 * 参数2: Y轴的放大倍数
 * 参数3: 原点在X坐标位置
 * 参数4: 原点在Y坐标位置
 */ 
canvas.scale(2, 4100,100);

这里写图片描述
Canvas旋转

/** 
 * 原点为中心,旋转30度(顺时针方向为正方向 )
 * 参数: 旋转角度 
 */
canvas.rotate(30);
/** 
 * 以(100,100)为中心,旋转30度,顺时针方向为正方向 
 * 参数: 旋转角度 
 */ 
canvas.rotate(30,100,100);

这里写图片描述

Canvas画布的错切

/**
 * 参数1:将画布在x方向上倾斜相应的角度,倾斜角度的tan值
 * 参数2:将画布在y方向上倾斜相应的角度,倾斜角度的tan值
canvas.skew(1,0);

实例

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Paint p = new Paint();

    p.setColor(Color.argb(50,255,100,100));
    canvas.drawRect(0,0,200,200,p); // 以原始Canvas画出一个矩形1

    canvas.translate(300,300); // 将Canvas平移(300,300)
    p.setColor(Color.argb(50,100,255,100));
    canvas.drawRect(0,0,200,200,p); // 矩形2

    canvas.rotate(30); // 将Canvas旋转30
    p.setColor(Color.argb(50,100,0,255));
    canvas.drawRect(0,0,200,200,p); // 矩形3

    canvas.scale(2, 2); // 将Canvas以原点为中心,放大两倍
    p.setColor(Color.argb(50,255,255,0));
    canvas.drawRect(0,0,200,200,p); // 矩形4

    // x 方向上倾斜45 度
    canvas.skew(1, 0);
    p.setColor(0x8800ff00);
    canvas.drawRect(new Rect(0, 0, 200, 200), p); // 矩形5

    // Y 方向上倾斜45 度
    canvas.skew(0, 1);
    p.setColor(Color.argb(60,201,81,205));
    canvas.drawRect(new Rect(0, 0, 200, 200), p); // 矩形6

}

这里写图片描述

Canvas保存和还原

Canvas提供了几个方法,让我们可以方便的对Canvas的状态进行更改和还原。
这些方法是:save()restore()restoreToCount(int saveCount)
我们在对Canvas进行平移、旋转、放大等操作时候,可以调用save()方法,将当前修改过的Canvas状态进行保存,调用restore() 方法后,会将Canvas还原成最近的一个save() 的状态。
save()方法还会有一个返回值,我们也可以调用restoreToCount(int saveCount)方法,将这个返回值作为参数传递进去,就可以将Canvas还原成某一个特定的save()状态。

canvas.translate(100,100); // 平移(100,100)
int save1 = canvas.save(); // 保存Canvas状态(状态1)
canvas.scale(2, 2); // 放大2倍
int save2 = canvas.save(); // 保存Canvas状态(状态2)
canvas.restore(); // 返回最新的save状态,即状态2
canvas.restoreToCount(save1); // 手动指定的返回到 状态1

画图

画文字

/** 
 * 参数2:默认是这个字符串的开始在屏幕的x轴位置,如果设置了paint.setTextAlign(Paint.Align.CENTER);那就是字符的中心距屏幕的x轴位置
 * 参数2:这个字符baseline在屏幕上的y轴位置 
 * 参数3:画笔对象 
 */
canvas.drawText("开始写字了!",50, 50, p);// 画文本
/** 
 * 参数2:要从第几个字开始绘制 
 * 参数3:要绘制到第几个文字 
 * 参数4:默认是这个字符串的开始在屏幕的x轴位置,如果设置了paint.setTextAlign(Paint.Align.CENTER);那就是字符的中心距屏幕的x轴位置
 * 参数5:这个字符baseline在屏幕上的y轴位置
 * 参数6:画笔对象 
 */
canvas.drawText("开始写字了!",2,5, 50, 50, p);// 画文本,结果为:“写字了”
/** 
 * 参数2:路径 
 * 参数3:距离路径开始位置的偏移量 
 * 参数4:距离路径上下的偏移量(可以为负数) 
 * 参数5:画笔对象 
 */
canvas.drawTextOnPath("1234567890101123123", path, 0, -50, p);

点击详细了解字符的baseline基线

画圆

/**
 * 参数1:圆心X 
 * 参数2:圆心Y 
 * 参数3:半径R 
 * 参数4:画笔对象 
 */           
canvas.drawCircle(200, 200, 100, p);

画线

/** 
 * 参数1:startX 
 * 参数2:startY 
 * 参数3:stopX 
 * 参数4:stopY 
 * 参数5:画笔对象 
 */
canvas.drawLine(100, 100, 300, 300, p);// 画线
/** 
 * 同时绘制多条线。 
 * 参数1:float数组:每四个一组为一条线。最后不足四个,就忽略那些值。 
 * 参数2:画笔对象 
 */
canvas.drawLines(new float[]{100,100,200,200,200,100,300,100}, p);

画椭圆

/* 
 *  RectF:表示坐标系中的一块矩形区域,并可以对其做一些简单操作。
 *  这块矩形区域,需要用左上和右下两个坐标点表示。
 *  参数1:float left 
 *  参数2:float top 
 *  参数3:float right 
 *  参数4:float bottom 
 */
RectF oval = new RectF(150, 200, 500, 400); 
canvas.drawOval(oval, p); // 画一个椭圆

画弧度

/**
 *  画圆弧
 *  参数1:RectF对象。 表示坐标系中的一块矩形区域,并可以对其做一些简单操作。
 *  这块矩形区域,需要用左上和右下两个坐标点表示。
 *  参数2:开始的角度。(水平向右为0度顺时针反向为正方向) 
 *  参数3:扫过的角度。(水平向右为0度顺时针方向为正方向) 
 *  参数4:是否和中心连线 
 *  参数5:画笔对象 
 */
canvas.drawArc(oval, 20, 180, false, p);

矩形

/** 
 *  矩形 
 *  参数1:float left 
 *  参数2:float top 
 *  参数3:float right 
 *  参数4:float bottom 
 */
canvas.drawRect(100, 100, 200, 200, p);

//画圆角矩形
RectF oval3 = new RectF(80, 260, 200, 300); // 设置个新的长方形
canvas.drawRoundRect(oval3, 20, 5, p); // 第二个参数是x半径,第三个参数是y半径

多边形

/**  
 * Path类封装复合(多轮廓几何图形的路径  
 * 由直线段*、二次曲线,和三次方曲线,也可画以油画。drawPath(路径、油漆),要么已填充的或抚摸  
 * (基于油漆的风格),或者可以用于剪断或画画的文本在路径。  
 */
Path path = new Path();  // 路径对象 
path.moveTo(80, 200); // 此点为多边形的起点    
path.lineTo(120, 250);    
path.lineTo(80, 250);    
//....  可以添加多个点。构成多边形  
path.close(); // 使终点和起点链接,构成封闭图形   
canvas.drawPath(path, p);

画贝塞尔曲线

p.setStyle(Style.STROKE);
Path path2=new Path();
path2.moveTo(100, 100); //设置Path的起点
/** 
 * 参数1、2:x1,y1为控制点的坐标值 
 * 参数3、4:x2,y2为终点的坐标值 
 */
path2.quadTo(300, 100, 400, 400); // 设置贝塞尔曲线的控制点坐标和终点坐标
path2.quadTo(500, 700, 800, 800);
canvas.drawPath(path2, p); //画出贝塞尔曲线

画点

/** 
 * 参数1、2:点的x、y坐标 
 */
canvas.drawPoint(60, 390, p); // 画一个点
/** 
 * 参数1:多个点,每两个值为一个点。最后个数不够两个的值,忽略。 
 */
canvas.drawPoints(new float[]{60,400,65,400,70,400}, p); // 画多个点

画图片

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
/** 
 * 参数1:bitmap对象 
 * 参数2:图像左边坐标点 
 * 参数3:图像上边坐标点 
 */
canvas.drawBitmap(bitmap, 200,300, p);

实例

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    /*
     * 方法 说明 drawRect 绘制矩形 drawCircle 绘制圆形 drawOval 绘制椭圆 drawPath 绘制任意多边形
     * drawLine 绘制直线 drawPoin 绘制点
     */
    // 创建画笔
    Paint p = new Paint();
    p.setColor(Color.BLACK); // 设置文字为黑色
    p.setTextSize(40); // 设置画笔粗细(即字体大小)

    // 画实心圆
    canvas.drawText("画实心圆", 5, 100, p); // 画文本
    canvas.drawCircle(220, 80, 50, p);

    // 画空心圆
    p.setStyle(Paint.Style.STROKE); // 空心
    canvas.drawText("画空心圆", 280, 100, p); // 画文本
    canvas.drawCircle(500, 80, 50, p);

    // 画实心锯齿圆
    p.setStyle(Paint.Style.FILL); // 实心
    canvas.drawText("画实心抗锯齿圆", 5, 200, p); // 画文本
    p.setAntiAlias(true); // 设置画笔的抗锯齿效果
    canvas.drawCircle(340, 180, 50, p);// 大圆

    // 画线
    canvas.drawText("画字符的baseline基线-fg", 5, 300, p);
    canvas.drawLine(5,300,600,300,p);

    // 画椭圆
    canvas.drawText("画实心椭圆", 5, 400, p);
    RectF rectF = new RectF(210, 310, 600, 450);
    canvas.drawOval(rectF,p);

    // 画空心椭圆
    p.setStyle(Paint.Style.STROKE);
    canvas.drawText("画空心椭圆", 610, 400, p);
    RectF rectF1 = new RectF(820, 310, 1050, 450);
    canvas.drawOval(rectF1,p);

    // 画空心弧度
    canvas.drawText("画空心弧度",5,500,p);
    p.setColor(Color.rgb(165,114,170));
    RectF rectF2 = new RectF(210, 410, 600, 550);
    canvas.drawArc(rectF2, -30, 240, true, p);

    // 画实心方角矩形
    p.setColor(Color.BLACK);
    canvas.drawText("画实心方角矩形",5,600,p);
    p.setStyle(Paint.Style.FILL);
    p.setColor(Color.rgb(165,114,170));
    canvas.drawRect(290,560,600,630,p);

    // 画实心圆角矩形
    p.setColor(Color.BLACK);
    canvas.drawText("画实心圆角矩形",5,700,p);
    p.setStyle(Paint.Style.FILL);
    p.setColor(Color.rgb(165,114,170));
    RectF rectF3 = new RectF(290,660,600,730);
    canvas.drawRoundRect(rectF3,20,20,p);

    // 画空心多边形
    p.setColor(Color.BLACK);
    canvas.drawText("画空心多边形", 5, 800, p);
    p.setStyle(Paint.Style.STROKE); //设置空心
    Path path = new Path(); // 路径对象
    path.moveTo(300, 740);
    path.lineTo(400, 740);
    path.lineTo(460, 780);
    path.lineTo(400, 820);
    path.lineTo(300, 820);
    path.lineTo(250, 780);
    path.close(); // 封闭
    canvas.drawPath(path, p);

    // 画实心贝塞尔曲线
    p.setColor(Color.BLACK);
    canvas.drawText("画实心贝塞尔曲线", 5, 900, p);
    p.setStyle(Paint.Style.FILL);
    Path path1=new Path();
    path1.moveTo(330, 830); // 设置Path的起点
    path1.quadTo(500, 980, 900, 1000); // 设置贝塞尔曲线的控制点坐标和终点坐标
    canvas.drawPath(path1, p); // 画出贝塞尔曲线

    // 画一个点
    canvas.drawText("画一个点", 5, 1100, p);
    p.setColor(Color.RED);
    p.setStrokeWidth(10); // 设置画笔的粗细
    canvas.drawPoint(180, 1100, p); // 画一个点

    //  画多个点
    p.setColor(Color.BLACK);
    canvas.drawText("画多个点", 5, 1200, p);
    p.setColor(Color.RED);
    p.setStrokeWidth(20);
    canvas.drawPoints(new float[]{180, 1200, 220,1200, 260, 1200}, p); // 画一个点

    // 画图片
    p.setColor(Color.BLACK);
    canvas.drawText("画图片", 5, 1300, p);
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
    canvas.drawBitmap(bitmap, 120,1210, p);

}

Demo效果图

这里写图片描述

源码点击此处下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值