安卓中Canvas,paint的Api详解

概述

我们通过在画布上绘画进行类比,如下:
Canvas:相当于画布,Bitmap提供内存,绘的画会保存在Bitmap中。
Paint:相当于画笔。
有了画笔和画笔我们就可以绘画了。

两种坐标系

Canvas绘图中牵扯到两种坐标系:Canvas坐标系与绘图坐标系。

  • Canvas坐标系
    Canvas坐标系指的是Canvas本身的坐标系,Canvas坐标系有且只有一个,且是唯一不变的,其坐标原点在View的左上角,从坐标原点向右为x轴的正半轴,从坐标原点向下为y轴的正半轴。

  • 绘图坐标系
    Canvas的drawXXX方法中传入的各种坐标指的都是绘图坐标系中的坐标,而非Canvas坐标系中的坐标。默认情况下,绘图坐标系与Canvas坐标系完全重合,即初始状况下,绘图坐标系的坐标原点也在View的左上角,从原点向右为x轴正半轴,从原点向下为y轴正半轴。但不同于Canvas坐标系,绘图坐标系并不是一成不变的,可以通过调用Canvas的translate方法平移坐标系,可以通过Canvas的rotate方法旋转坐标系,还可以通过Canvas的scale方法缩放坐标系,而且需要注意的是,translate、rotate、scale的操作都是基于当前绘图坐标系的,而不是基于Canvas坐标系,一旦通过以上方法对坐标系进行了操作之后,当前绘图坐标系就变化了,以后绘图都是基于更新的绘图坐标系了。也就是说,真正对我们绘图有用的是绘图坐标系而非Canvas坐标系

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

paint的常用设置

参考文章Android Paint,Canvas api 详解
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对象颜色12345678

设置不透明度

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

设置是否抗锯齿

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

设置文本缩放倍数

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

设置字体大小

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

设置下划线

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

设置实心还是空心

在画面状的图形时,如果Paint的style是FILL,那么绘制的就是填充面;如果是STROKE,那么绘制的就是轮廓线。

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

设置画笔的粗细

paint.setStrokeWidth(10);

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

画图

画文字

/** 
 * 参数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);

画图片

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

我在res/drawable目录下放置了一张android的图片,下面对上面的代码进行说明:

  1. Canvas的drawBitmap有多个重载方法,最简单的方法签名是:public void drawBitmap (Bitmap
    bitmap, float left, float top, Paint
    paint)该方法除了传入bitmap对象外,还需要传入left和top,left和top组成了一个坐标,决定了在Canvas中从哪个地方绘制Bitmap。在我们的代码中,left和top都设置为0,所以我们就在Canvas的左上角绘制了bitmap。

  2. drawBitmap还有一个比较实用的方法,其方法签名是:public void drawBitmap (Bitmap bitmap,
    Rect src, Rect dst, Paint
    paint)该方法有两个功能:1.只绘制原有bitmap对象的一部分,2.还可以将要绘制的bitmap缩放到指定的区域。

    1. 只绘制原有bitmap对象的一部分
      我们知道Bitmap是一个矩形,其是有宽度和高度的,也就说以bitmap对象本身作为坐标系(原点在bitmap左上角),我们可以构建一个Rect对象,如果满足left为0,top为0,right为bitmap的宽度,bottom为bitmap的高度,那么就说名我们要绘制整个Bitmap。但是有时候我们只想绘制Bitmap的一部分,例如我们上面的图中所示,我们想只绘制Android图像的头部区域怎么办呢?办法是我们构建一个Rect对象,定义我们要绘制Bitmap的哪些部位。
      比如我们通过代码srcRect.bottom = (int)(0.33 *
      bitmap.getHeight())指定了我们只绘制bitmap对象头部1/3的位置,即Android图像的头部,这样我们用该指定的srcRect绘制bitmap时只绘制了其头部位置。需要特别注意的是,srcRect中left、top、right、bottom的值都是以Bitmap本身的局部坐标系为基础的。将要绘制的bitmap缩放到指定的区域

    2. 有时候我们需要将原有的bitmap进行放大或缩小,如上图所示,我们将原有图片放大了,这怎么做呢?我们需要指定RectF类型的参数dstRectF,以便告诉Android将srcRect中定义的bitmap缩放到哪里。即Android会将srcRect中定义的bitmap缩放到dstRectF区域范围内。需要注意的是,此处的dstRecF是绘图坐标系中的坐标,不是Bitmap本身的局部坐标系。我们在代码中保证了dstRecF的长宽比与srcRect中的长宽比相同,这样不会导致图片长宽比例变形,效果见上图中的第二个放大的图形。
      参考连接添加链接描述

一个特殊的调用:
canvas.drawbitmap(bitmap,0,0,null),Paint 的参数为null,表示没有画笔,也就不会进行画画,只有显示图片的功能。

对canvas的进一步理解

Canvas canvas = new Canvas(bmp);

创建了一个包含bmp这个位图的canvas.==canvas的绘制效果会作用于bmp上。

canvas.drawBitmap(mBitmap,0,0,paint);

将mBitmap这个位图用paint画在canvas上,==>直接把bmp的数据变成了mBitmap.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值