【Android】21.2 Canvas和Paint

分类:C#、Android、VS2015;

创建日期:2016-03-19

一、Canvas对象简介

画布(Canvas对象)是与System.Drawing或iOS核心图形等传统框架非常类似的另一种图形图像绘制技术,该对象提供了创建2D图形的最大控制,利用它可解决难以处理画板资源的情况。例如,绘制自定义滑块控件的外观等。

可以把Canvas理解成系统提供给我们的一块内存区域(但实际上它只是一套绘图API,真正的内存是下面的Bitmap),而且它还提供了一整套对这个内存区域进行操作的方法,所有的这些操作都是绘图API。也就是说,在这种方式下我们已经能一笔一划或者使用Graphic来绘制我们需要的东西了,要画什么要显示什么都由我们自己来控制。

1、Canvas API

画板(Drawables)虽然强大但有其局限性,有些复杂的功能无法用它来实现。例如,将滤镜应用于由设备上的照相机拍摄的图片实现红眼特效等。要实现这些功能,可利用Canvas API对其进行细粒度控制,这样就可以有选择性地改变图片的特定部分中的颜色。

Canvas API绘制2D图形非常类似于画家在模型的不同部分一层一层地涂抹不同颜色的油漆。或者说,对Canvas的每个绘制操作都将覆盖底层位图的一部分,如果和原来绘制的部分重叠则覆盖。

2、获取Canvas对象

有两种方式得到一个Canvas对象。

(1)第1种方式

定义Bitmap对象,然后实例化一个Canvas对象。例如:

Bitmap bitmap = Bitmap.CreateBitmap(100, 100, Bitmap.Config.Argb8888);

Canvas canvas = new Canvas(b);

(2)第2种方式

通过重写视图类的OnDraw()回调方法获取一个Canvas对象。

3、操作Canvas对象

得到Canvas对象后,就可以对它进行操作了,例如:

l Canvas.DrawPaint(Paint p) – 用指定的Paint对象填充整个位图画布。

l Canvas.DrawPath(Path path, Paint paint) –用指定的Paint对象绘制指定的几何形状。

l Canvas.DrawText(String text, float x, float y, Paint paint) –用指定的Paint对象在画布的(x,y)坐标处绘制文本,比如用Paint对象指定颜色等。

二、Paint对象常用属性和方法

Canvas是通过Paint对象来操作的,所以这里先说一下Paint对象的基本用法。

Paint用于指定图形或者文字的颜色、大小等。常用属性和方法如下。

1、消除锯齿

AntiAlias属性:是否消除锯齿,true:消除锯齿,false:不消除。

2、画笔颜色

Color属性:获取或设置颜色。

3、alpha不透明度

Alpha属性:获取或设置alpha不透明度,范围为0~255。

4、字体大小

TextSize属性:获取或设置字体大小。

5、轮廓和填充

SetStyle()方法:设置画笔样式,是绘制轮廓还是填充。

StrokeWidth属性:获取或设置轮廓的宽度。

6、设置Paint对象颜色

SetARGB(int a, int r, int g, int b)

设置 Paint对象颜色,参数1为alpha不透明度(0~255)。

7、设置文本缩放倍数

SetTextScaleX(float scaleX)

设置文本缩放倍数,1.0f为原始大小。

8、设置下划线

SetUnderlineText(booleanunderlineText)

三、Canvas基本用法

这种方式根据环境还分为两种:一种就是使用普通View的canvas画图,还有一种就是使用专门的SurfaceView的canvas来画图。两种的主要是区别就是可以在SurfaceView中定义一个专门的线程来完成画图工作,应用程序不需要等待View的刷图,提高性能。前面一种适合处理量比较小,帧率比较小的动画,比如说象棋游戏之类的;而后一种主要用在游戏,高品质动画方面的画图。

下面是Canvas类常用的方法。

1、绘制矩形

DrawRect(RectF rect, Paint paint)

绘制矩形区域,参数rect表示一个居心的大小。

2、绘制路径

DrawPath(Path path, Paint paint)

绘制一个路径,参数path为路径对象。

3、贴图

DrawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)

参数bitmap是Bitmap对象,参数src是源区域(这里是bitmap),参数dst是目标区域(应该在canvas的位置和大小),参数paint是Paint画刷对象。

注意如果缩放和拉伸,当原始Rect不等于目标Rect时,该方法的性能将会有大幅损失。

4、画线

DrawLine(float startX, float startY, float stopX, float stopY, Paintpaint)

前两个参数是起始点的x、y坐标位置,后两个参数是终点的x、y坐标位置,最后一个参数为Paint 画刷对象。

5、画点

DrawPoint(float x, float y, Paint paint)

前两个参数为x、y坐标,第3个参数为Paint对象。

6、绘制文字

drawText(String text, float x, floaty, Paint paint)

Canvas类除了上面的还可以描绘文字,参数一是string类型的文本,参数2是x轴,参数3是y轴,参数4是Paint对象。

7、画椭圆

DrawOval(RectF oval, Paint paint)

参数1是椭圆的外切矩形,参数2为paint对象;

8、画圆

drawCircle(float cx, float cy, float radius,Paint paint)

参数1是中心点的x轴,参数2是中心点的y轴,参数3是半径。

9、画弧

drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

参数1是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、电弧,参数2是起始角(度)在电弧的开始,参数3扫描角(度)开始顺时针测量的,参数4如果为true则包括椭圆中心的电弧并关闭它,如果为false表示这是一个弧线;参数5是Paint对象;

四、使用Shader类渲染图形

你可能经常看到某些界面(比如屏幕保护或者播放器)中有一些非常绚丽的图形,其实这些都是在原有图形的基础上进行渲染的效果。

Android提供了一个Shader类来实现渲染效果,这是一个抽象类,其子类很多,比如BitmapShader类(位图渲染)、ComposeShader类(混合渲染)、LinearGradient类(线性渲染)、RadialGradient类(仿射渲染)、SweepGradient类(梯度渲染)等。通过Paint对象的SetShader()方法可设置使用的这些渲染对象。

下面的代码演示了其基本用法:

Paint p = new Paint();

Shader mShader = new LinearGradient(0, 0, 100, 100,

new int[] { Color.Red, Color.Green, Color.Yellow, Color.LightGray }, null, Shader.TileMode.Repeat);

p.SetShader(mShader);

五、示例

1、运行截图

2、设计步骤

(1)添加ch2102Main.axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:id="@+id/ch2102_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

(2)添加ch2102MainActivity.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace MyDemos.SrcDemos
{
    [Activity(Label = "【例21-2】Canvas基本用法")]
    public class ch2102MainActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            SetContentView(Resource.Layout.ch2102Main);
            var layout = FindViewById<LinearLayout>(Resource.Id.ch2102_root);
            MyView view = new MyView(this);
            view.SetMinimumWidth(layout.Width - 20);
            view.SetMinimumHeight(layout.Height - 20);
            layout.AddView(view);
        }
    }

    public class MyView : View
    {
        private Context context;

        public MyView(Context context) : base(context)
        {
            this.context = context;
        }

        private void DrawText(Canvas canvas, string text, int x, int y)
        {
            using (Paint p = new Paint())
            {
                p.Color = Color.Black;
                p.TextSize = 24;
                p.AntiAlias = true;   // 消除锯齿
                canvas.DrawText(text, x, y, p);
            }
        }

        protected override void OnDraw(Canvas canvas)
        {
            base.OnDraw(canvas);

            Color drawColor = Color.Red;
            Paint p = new Paint();
            p.Color = drawColor;
            int x1 = 40, y1 = 60, dy = 80;

            DrawText(canvas, "画圆和直线:", x1, y1);
            canvas.DrawCircle(x1 + 300, y1 + 20, 20, p);// 小圆
            canvas.DrawCircle(x1 + 400, y1 + 20, 40, p);// 大圆
            canvas.DrawLine(0, y1 + 20, 600, y1 + 20, p);// 画线  

            y1 += dy;
            DrawText(canvas, "画弧线:", x1, y1);
            p.SetStyle(Paint.Style.Stroke);//仅绘制轮廓
            RectF oval1 = new RectF(x1 + 150, y1, x1 + 180, y1 + 30);
            canvas.DrawArc(oval1, 180, 180, false, p);//小弧形
            oval1.Set(x1 + 190, y1, x1 + 220, y1 + 30);
            canvas.DrawArc(oval1, 180, 180, false, p);//小弧形
            oval1.Set(x1 + 160, y1 + 45, x1 + 210, y1 + 60);
            canvas.DrawArc(oval1, 0, 180, false, p);//小弧形  

            y1 += dy;
            DrawText(canvas, "画矩形:", x1, y1);
            p.SetStyle(Paint.Style.Fill);//仅填充
            canvas.DrawRect(x1 + 100, y1, x1 + 160, y1 + 60, p);// 正方形
            canvas.DrawRect(x1 + 200, y1, x1 + 360, y1 + 60, p);// 长方形  

            y1 += dy;
            DrawText(canvas, "画扇形和椭圆:", x1, y1);
            Shader mShader = new LinearGradient(0, 0, 100, 100,
                new int[] { Color.Red, Color.Green, Color.Black, Color.Yellow, Color.LightGray },
                null, Shader.TileMode.Repeat);
            p.SetShader(mShader);
            RectF oval2 = new RectF(x1 + 100, y1, x1 + 200, y1 + 50);// 设置个新的长方形,扫描测量
            //true:画扇形,false:画弧线
            canvas.DrawArc(oval2, x1 + 300, y1 + 30, true, p);
            //画椭圆
            oval2.Set(x1 + 350, y1, x1 + 380, y1 + dy);
            canvas.DrawOval(oval2, p);
            //true:画扇形,false:画弧线
            RectF oval3 = new RectF(x1 + 450, y1, x1 + 500, y1 + 30);
            canvas.DrawArc(oval3, x1 + 480, y1 + 30, true, p);

            y1 += dy;
            DrawText(canvas, "画三角形:", x1, y1);
            Path path = new Path();
            path.MoveTo(x1 + 180, y1);// 起点(顶角所在的点)
            path.LineTo(x1 + 80, y1 + 50);
            path.LineTo(x1 + 260, y1 + 50);
            path.Close(); // 使这些点构成封闭的多边形
            canvas.DrawPath(path, p);

            y1 += dy;
            DrawText(canvas, "画多边形:", x1, y1);
            // 画六连形(可绘制任意多边形)
            p.SetStyle(Paint.Style.Stroke);//仅绘制轮廓
            Path path1 = new Path();
            path1.MoveTo(x1 + 300, y1); //左上角
            path1.LineTo(x1 + 350, y1);  //上面横线
            path1.LineTo(x1 + 400, y1 + 40); //右上方斜线
            path1.LineTo(x1 + 400, y1 + 80); //右方竖线
            path1.LineTo(x1 + 350, y1 + 120); //右下方斜线
            path1.LineTo(x1 + 300, y1 + 120);  //下方横线
            path1.Close(); //封闭
            canvas.DrawPath(path1, p);

            y1 += dy + 50;
            DrawText(canvas, "画圆角矩形:", x1, y1);
            p.SetStyle(Paint.Style.Fill);//填充
            RectF oval4 = new RectF(x1 + 80, y1, x1 + 280, y1 + 50);
            //20:横向圆角的角度,15:纵向圆角的角度
            canvas.DrawRoundRect(oval4, 20, 15, p);

            y1 += dy;
            DrawText(canvas, "贴图:", x1, y1);
            Bitmap bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.ch03ic_launcher);
            canvas.DrawBitmap(bitmap, x1 + 200, y1, p);
        }
    }
}
时间: 2024-10-19 17:56:37

【Android】21.2 Canvas和Paint的相关文章

Android中使用Canvas和Paint绘制一个安卓机器人

场景 在Android中画笔使用Paint类,画布使用Canvas类来表示. 绘图的基本步骤 首先编写一个继承自View的自定义View类,然后重写其onDraw方法,最后把自定义的view添加到actvity中. 效果 注: 博客: https://blog.csdn.net/badao_liumang_qizhi关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 首先在要显示的Activity的布局文件中修改为FrameLayout并添加一个id. <?xml vers

android 绘图之Canvas,Paint类

Canvas,Paint 1.在android 绘图但中经常要用到Canvas和Paint类,Canvas好比是一张画布,上面已经有你想绘制图画的轮廓了,而Paint就好比是画笔,就要给Canvas进行添色等操作. 这两个类通常都是在onDraw(Canvas canvas)方法中用的. 2.Bitmap:代表一张位图,BitmapDrawable里封装的突变就是一个Bitmao对象 3.Canvas里面有一些例如: drawArc(参数) 绘制弧 drawBitmao(Bitmap bitma

Android使用学习之画图(Canvas,Paint)与手势感应及其应用(乒乓球小游戏)

作为一个没有学习Android的菜鸟,近期一直在工作之外努力地学习的Android的使用. 这周看了下Android的画图.主要是Canvas,Paint等,感觉须要实践下.下午正好有空,就想整一个乒乓球的游戏,算是巩固学的知识. 首先,须要了解下Android的画图须要掌握的经常使用类.包含Canvas,就像一个画板一样,全部的东西都是在其上画的.Paint就是画笔.用其能够画各种基本图形和文字.       Canvas和Paint经常使用的方法就不列举了,这种东西网上到处是.有了这两个东西

Android中android.graphics下面的绘制图形类Canvas,Paint,Bitmap,Drawable

1.概念区别: 很多网友刚刚开始学习Android平台,对于Drawable.Bitmap.Canvas和Paint它们之间的概念不是很清楚, 其实它们除了Drawable外早在Sun的J2ME中就已经出现了,但是在Android平台中,Bitmap.Canvas相关的都有所变化. 首先让我们理解下Android平台中的显示类是View,但是还提供了底层图形类android.graphics,今天所说的这些均为graphics底层图形接口. Bitmap - 称作位图,一般位图的文件格式后缀为b

Android 绘图之一:Canvas 及 Paint 简介

前言 除了使用已有的图片之外,Android应用常常需要在运行时根据场景动态生成2D图片,比如手机游戏,这就需要借助于Android2D绘图的支持.本篇博客主要讲解一下Android下使用Canvas进行绘图的相关操作.最后将以一个简单的Demo演示如何使用Canvas在ImageView上画图并保存. 画布Canvas 在Android下进行2D绘图需要Canvas类的支持,它位于"android.graphics.Canvas"包下,直译过来为画布的意思,用于完成在View上的绘图

Android 2D绘图解析之 Canvas,Paint

原创文章,转载请注明 ( 来自:http://blog.csdn.net/leejizhou/article/details/51524948 李济洲的博客 ) [Android 2D绘图解析]系列文章将全面介绍Android绘图相关,这篇简单介绍下如何利用Android API进行一些简单图形的绘制,绘图的前提是需要继承自View,然后重写它的onDraw(Canvas canvas) 方法即可. 首先我们新建一个类继承自View,并重写onDraw方法. package com.leejz.

Android查缺补漏(View篇)--自定义View利器Canvas和Paint详解

上篇文章介绍了自定义View的创建流程,从宏观上给出了一个自定义View的创建步骤,本篇是上一篇文章的延续,介绍了自定义View中两个必不可少的工具Canvas和Paint,从细节上更进一步的讲解自定义View的详细绘制方法.如果把自定义View比作盖一座房子,那么上篇文章就相当于教会了我们怎么一步步的搭建房子的骨架,而本篇文章将要教会我们的是为房子的骨架添砖加瓦直至成型,甚至是怎么装修. Canvas 为了后文更为方便的讲解Canvas的常用方法的使用,我们先来做一些准备工作,创建一个自定义V

Android--Drawable、Bitmap、Canvas和Paint的关系

Drawable.Bitmap.Canvas和Paint 除了Drawable外早在Sun的J2ME中就已经出现了,但是在Android平台中,Bitmap.Canvas相关的都有所变化. 首先让我们理解下Android平台中的显示类是View,但是还提供了底层图形类android.graphics,今天所说的这些均为graphics底层图形接口. (1)Bitmap - 称作位图,一般位图的文件格式后缀为bmp,当然编码器也有很多如RGB565.RGB888.作为一种逐像素的显示对象执行效率高

Android 中的Canvas画图

Android中有一个Canvas类,Canvas类就是表示一块画布,你可以在上面画你想画的东西.当然,你还可以设置画布的属性,如画布的颜色/尺寸等.Canvas提供了如下一些方法: Canvas():创建一个空的画布,可以使用setBitmap()方法来设置绘制的具体画布: Canvas(Bitmapbitmap):以bitmap对象创建一个画布,则将内容都绘制在bitmap上,bitmap不得为null; Canvas(GLgl):在绘制3D效果时使用,与OpenGL有关: drawColo