Android图形处理-Canvas

Android图形处理-Canvas

Canvas

Canvas绘图有三个基本要素:Canvas、绘图坐标系以及Paint。Canvas是画布,我们通过Canvas的各种drawXXX方法将图形绘制到Canvas上面,在drawXXX方法中我们需要传入要绘制的图形的坐标形状,还要传入一个画笔Paint.

两个坐标系

  1. canvas坐标系是固定的
  2. 画图坐标系可以移动:可以通过调用Canvas的translate方法平移坐标系,可以通过Canvas的rotate方法旋转坐标系,真正对我们绘图有用的是绘图坐标系而非Canvas坐标系。

常见方法

drawARGB

Canvas中的drawARGB可以用来对整个Canvas以某种统一的颜色整体绘制,四个参数分别是Alpha、Red、Green、Blue,取值都是0-255

就是相当于填充的作用

drawText

Android中的画笔有两种Paint和TextPaint,我们可以Paint来画其他的图形:点、线、矩形、椭圆等。TextPaint继承自Paint,是专门用来画文本的,由于TextPaint继承自Paint,所以也可以用TextPaint画点、线、面、矩形、椭圆等图形

画笔Paint控制着所绘制的图形的具体外观,Paint默认的字体大小为12px,在绘制文本时我们往往要考虑密度density设置合适的字体大小。画笔的默认颜色为黑色,默认的style为FILL,默认的cap为BUTT,默认的线宽为0

sp161107_204430

drawPoint

就是一个设置point(点)的形状:

        //绘制Cap为ROUND的点
        paint.setStrokeCap(ROUND);
        canvas.drawPoint(x, y, paint);
drawRect
        Rect rect = new Rect(0, 10, 50, 60);
        canvas.drawRect(rect,paint);

rect的四个参数分别是left,top,right,bottom

drawCircle
canvas.drawCircle(200,200,50,paint);

就是圆心的坐标和半径

画出一个环

有两个思路一个是画出来两个圆,另外一个是设置画笔的模式:
sp161107_192513

        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);

Paint通过setStyle方法设置要绘制的类型,style有取三种值:Paint.Style.FILL、Paint.Style.STROKE和Paint.Style.FILL_AND_STROKE。

  • 当style为FILL时,绘制是填充面,FILL是Paint默认的style;
  • 当style为STROKE时,绘制的是图形的轮廓线;
  • 当style为FILL_AND_STROKE时,同时绘制填充面和轮廓线,不过这种情况用的不多,因为填充面和轮廓线是用同一种颜色绘制的,区分不出轮廓线的效果。
drawOval

注意椭圆使用的是RectF不是Rect,画出一个空心椭圆:

sp161107_193127

        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);
        RectF rectF = new RectF(0, 10, 150, 90);
        canvas.drawOval(rectF, paint);

画出一个带有轮廓的椭圆:
sp161107_193237

本质就是画出两个椭圆:

//      画出内部
        paint.setStrokeWidth(5);
        RectF rectF = new RectF(0, 10, 150, 90);
        canvas.drawOval(rectF, paint);
//      画出外部轮廓
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.BLUE);
        canvas.drawOval(rectF, paint);

drawText具体使用

在绘制字体之前一定要先移动canvas否则会盖住字体

绘制正常文字

        Paint paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setTextSize(50);
        canvas.save();
        canvas.translate(0, 50);
        canvas.drawText("你好", 0, 0, paint);
        canvas.restore();

注意canvas.translate(0, 50)要先平移画布

canvas.drawText(“你好”, 0, 0, paint)两个整形参数分别代表的是在水平和垂直方向的偏移量

绘制带有对齐方向的文字

paint.setTextAlign(Paint.Align.LEFT)设置文字对齐的方向

注意这里的居中对齐是整个文字的中间正好在绘图坐标的原点

        Paint paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setTextSize(50);
        paint.setTextAlign(Paint.Align.CENTER);

        canvas.save();
//        canvas.translate(width/2, 50);
        canvas.translate(0, 50);
        canvas.drawText("你好", 0, 0, paint);
        canvas.restore();

这种情况绘制出只有一个字:

sp161107_183015

而要显示出你,就是先移动坐标系:

        Paint paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setTextSize(50);
        paint.setTextAlign(Paint.Align.CENTER);

        canvas.save();
        canvas.translate(width/2, 50);
//        canvas.translate(0, 50);
        canvas.drawText("你好", 0, 0, paint);
        canvas.restore();

sp161107_182656

就是你好的中间正好是绘图的坐标原点

所以绘制右对齐要先向右移动一个画布的距离:

        Paint paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setTextSize(50);
        paint.setTextAlign(Paint.Align.RIGHT);

        canvas.save();
        canvas.translate(width, 50);
//        canvas.translate(0, 50);
        canvas.drawText("你好", 0, 0, paint);
        canvas.restore();

sp161107_183308

这几个启动的核心是相对于字体而言的,就是居中对齐就找字体的中间,右对齐就找字体的右侧,而永远对齐画布的左侧

绘制带有下划线和加粗的字体

        Paint paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setTextSize(50);
        paint.setTextAlign(Paint.Align.LEFT);
//      设置下划线
        paint.setUnderlineText(true);
//      设置加粗
        paint.setFakeBoldText(true);
        canvas.save();
//        canvas.translate(width, 50);
        canvas.translate(0, 50);
        canvas.drawText("你好", 0, 0, paint);
        canvas.restore();

sp161107_183745

drawArc具体使用

public void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
  • oval是RecF类型的对象,其定义了椭圆的形状。
  • startAngle指的是绘制的起始角度,钟表的3点位置对应着0度,如果传入的startAngle小于0或者大于等于360,那么用startAngle对360进行取模后作为起始绘制角度。
  • sweepAngle指的是从startAngle开始沿着钟表的顺时针方向旋转扫过的角度。如果sweepAngle大于等于360,那么会绘制完整的椭圆弧。如果sweepAngle小于0,那么会用sweepAngle对360进行取模后作为扫过的角度。
  • useCenter是个boolean值,如果为true,表示在绘制完弧之后,用椭圆的中心点连接弧上的起点和终点以闭合弧;如果值为false,表示在绘制完弧之后,弧的起点和终点直接连接,不经过椭圆的中心点。

drawOval方法可以看做是drawArc方法的一种特例

画出一个椭圆

drawArc可以和drawOval一样都能够画出一个椭圆

        RectF rectF = new RectF(0, 10, 150, 90);
        canvas.drawArc(rectF, 0, 360, true, paint);

注意开始的角度是水平向右,方向是顺时针

画出任意角度的椭圆

        RectF rectF = new RectF(0, 10, 150, 90);
        canvas.drawArc(rectF, -20, 60, true, paint);

sp161107_193807

画出一个椭圆的外部弧

        RectF rectF = new RectF(0, 10, 150, 90);
        canvas.drawArc(rectF, -20, 60, false, paint);

sp161107_193920

只是把useCenter设置为false,注意第一个参数是开始角度,第二个参数是跨国角度

只是画出轮廓线

在上面的代码中更新设置画笔的样式:

sp161107_194031

        paint.setStyle(Paint.Style.STROKE);
        RectF rectF = new RectF(0, 10, 150, 90);
        canvas.drawArc(rectF, -20, 60, false, paint);

drawPath具体使用

在Android中,Path是一种线条的组合图形,其可以由直线、二次曲线、三次曲线、椭圆的弧等组成。Path既可以画线条,也可以画填充面

使用path画出图形

首先要设置画笔是填充模式Paint.Style.FILL然后在调用addXX方法画出各种形状

sp161107_195550

        paint.setStyle(Paint.Style.FILL);
//      添加椭圆
        RectF rectF = new RectF(0, 10, 150, 90);
        Path path = new Path();
        path.addOval(rectF, Path.Direction.CCW);
//      添加圆
        path.addCircle(220,50,50, Path.Direction.CCW);
//      添加矩形
        RectF rect = new RectF(300, 20, 400, 120);
        path.addRect(rect, Path.Direction.CCW);

        canvas.drawPath(path,paint);

画出空心的图形

只要在上面的代码中更改一点:
sp161107_195700

        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);

画出任意弧度

注意画直线的时候要先moveTo然后在lineTo

        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);
        Path path = new Path();
//      画出一段直线
        path.moveTo(0, 0);
        path.lineTo(100, 50);
//      添加一个四分之一的圆弧,当两个点没有连接上的时候,系统会自动创建一个直线连接
        RectF rectF = new RectF(20, 50, 180, 130);
        path.arcTo(rectF, 270, 90);
        path.lineTo(270, 90);
//       画出一个二阶贝塞尔曲线
        path.moveTo(270, 90);
        path.quadTo(80, 180, 500, 500);

        canvas.drawPath(path, paint);

sp161107_202040

drawBitmap

sp161107_204016

        Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.love);

        canvas.drawBitmap(bitmap, 0, 0, paint);
//        canvas.drawBitmap(bitmap,0,0,paint);
        Rect srcRect = new Rect();
        srcRect.left = 0;
        srcRect.right = bitmap.getWidth();
        srcRect.top = 0;
        srcRect.bottom = (int) (0.33 * bitmap.getHeight());

        //dstRecF定义了要将绘制的Bitmap拉伸到哪里
        RectF dstRecF = new RectF();
        dstRecF.left = bitmap.getWidth();
        dstRecF.right = canvas.getWidth();
        dstRecF.top = bitmap.getHeight();
        dstRecF.bottom = bitmap.getHeight() * 2;

        canvas.drawBitmap(bitmap, srcRect, dstRecF, paint);
public void drawBitmap (Bitmap bitmap, float left, float top, Paint paint)

该方法除了传入bitmap对象外,还需要传入left和top,left和top组成了一个坐标,决定了在Canvas中从哪个地方绘制Bitmap。在我们的代码中,left和top都设置为0,所以我们就在Canvas的左上角绘制了bitmap。

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

该方法有两个功能:1.只绘制原有bitmap对象的一部分,2.还可以将要绘制的bitmap缩放到指定的区域。

转载自:Android图形处理-Canvas

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值