分类: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 - );
view.SetMinimumHeight(layout.Height - );
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 = ;
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 = , y1 = , dy = ; DrawText(canvas, "画圆和直线:", x1, y1);
canvas.DrawCircle(x1 + , y1 + , , p);// 小圆
canvas.DrawCircle(x1 + , y1 + , , p);// 大圆
canvas.DrawLine(, y1 + , , y1 + , p);// 画线 y1 += dy;
DrawText(canvas, "画弧线:", x1, y1);
p.SetStyle(Paint.Style.Stroke);//仅绘制轮廓
RectF oval1 = new RectF(x1 + , y1, x1 + , y1 + );
canvas.DrawArc(oval1, , , false, p);//小弧形
oval1.Set(x1 + , y1, x1 + , y1 + );
canvas.DrawArc(oval1, , , false, p);//小弧形
oval1.Set(x1 + , y1 + , x1 + , y1 + );
canvas.DrawArc(oval1, , , false, p);//小弧形 y1 += dy;
DrawText(canvas, "画矩形:", x1, y1);
p.SetStyle(Paint.Style.Fill);//仅填充
canvas.DrawRect(x1 + , y1, x1 + , y1 + , p);// 正方形
canvas.DrawRect(x1 + , y1, x1 + , y1 + , p);// 长方形 y1 += dy;
DrawText(canvas, "画扇形和椭圆:", x1, y1);
Shader mShader = new LinearGradient(, , , ,
new int[] { Color.Red, Color.Green, Color.Black, Color.Yellow, Color.LightGray },
null, Shader.TileMode.Repeat);
p.SetShader(mShader);
RectF oval2 = new RectF(x1 + , y1, x1 + , y1 + );// 设置个新的长方形,扫描测量
//true:画扇形,false:画弧线
canvas.DrawArc(oval2, x1 + , y1 + , true, p);
//画椭圆
oval2.Set(x1 + , y1, x1 + , y1 + dy);
canvas.DrawOval(oval2, p);
//true:画扇形,false:画弧线
RectF oval3 = new RectF(x1 + , y1, x1 + , y1 + );
canvas.DrawArc(oval3, x1 + , y1 + , true, p); y1 += dy;
DrawText(canvas, "画三角形:", x1, y1);
Path path = new Path();
path.MoveTo(x1 + , y1);// 起点(顶角所在的点)
path.LineTo(x1 + , y1 + );
path.LineTo(x1 + , y1 + );
path.Close(); // 使这些点构成封闭的多边形
canvas.DrawPath(path, p); y1 += dy;
DrawText(canvas, "画多边形:", x1, y1);
// 画六连形(可绘制任意多边形)
p.SetStyle(Paint.Style.Stroke);//仅绘制轮廓
Path path1 = new Path();
path1.MoveTo(x1 + , y1); //左上角
path1.LineTo(x1 + , y1); //上面横线
path1.LineTo(x1 + , y1 + ); //右上方斜线
path1.LineTo(x1 + , y1 + ); //右方竖线
path1.LineTo(x1 + , y1 + ); //右下方斜线
path1.LineTo(x1 + , y1 + ); //下方横线
path1.Close(); //封闭
canvas.DrawPath(path1, p); y1 += dy + ;
DrawText(canvas, "画圆角矩形:", x1, y1);
p.SetStyle(Paint.Style.Fill);//填充
RectF oval4 = new RectF(x1 + , y1, x1 + , y1 + );
//20:横向圆角的角度,15:纵向圆角的角度
canvas.DrawRoundRect(oval4, , , p); y1 += dy;
DrawText(canvas, "贴图:", x1, y1);
Bitmap bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.ch03ic_launcher);
canvas.DrawBitmap(bitmap, x1 + , y1, p);
}
}
}

【Android】21.2 2D图形图像处理(Canvas和Paint)的更多相关文章

  1. 【Android】第21章 2D图形和动画

    分类:C#.Android.VS2015: 创建日期:2016-03-19 一.简介 Android系统定义了一系列独立的图形处理类,其中,2D图形处理类分别位于以下命名空间: Android.Gra ...

  2. android学习笔记43——图形图像处理3——Path

    Path类 Path类可以预先在View上将N个点连成一条“路径”,然后调用Canavas的drawPath(path,paint)即可沿着路径绘制图形. android还为路径绘制提供了PathEf ...

  3. android学习笔记42——图形图像处理2——绘图

    绘图 android的绘图应该继承View组件,并重写onDraw(Canvas canvas)方法即可. 重写onDraw(Canvas canvas)方法时涉及一个绘图API:Canvas,Can ...

  4. android学习笔记41——图形图像处理1

    图像图像处理 ImageView:用于显示普通静态图片: AnimationDrawable:用于开发逐帧动画: Animation:用于对普通图片使用补间动画: Bitmap.BitmapFacto ...

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

    作为一个没有学习Android的菜鸟,近期一直在工作之外努力地学习的Android的使用. 这周看了下Android的画图.主要是Canvas,Paint等,感觉须要实践下.下午正好有空,就想整一个乒 ...

  6. 自定义View(4)Canvas和Paint常用绘制函数

    画布Canvas 在Android下进行2D绘图需要Canvas类的支持,它位于"android.graphics.Canvas"包下,直译过来为画布的意思,用于完成在View上的 ...

  7. HTML5图形图像处理技术研究

    摘要:图形图像处理平台大部分是传统的C/S架构的桌面应用程序,维护困难,共享性差,而B/S架构的Web程序具有易维护.易共享的优点.本文研究了基于HTML5的Web图形图像处理技术,用HTML5实现了 ...

  8. 【转】android Graphics(四):canvas变换与操作

    android Graphics(四):canvas变换与操作 分类: 5.andriod开发2014-09-05 15:05 5877人阅读 评论(18) 收藏 举报   目录(?)[+]   前言 ...

  9. 图形绘制 Canvas Paint Path 详解

    图形绘制简介        Android中使用图形处理引擎,2D部分是android SDK内部自己提供,3D部分是用Open GL ES 1.0.大部分2D使用的api都在android.grap ...

随机推荐

  1. GET 和 POST的区别

    1.最普遍的答案 GET使用URL或Cookie传参.而POST将数据放在BODY中. GET的URL会有长度上的限制,则POST的数据则可以非常大. POST比GET安全,因为数据在地址栏上不可见. ...

  2. Hibernate(十三)命名查询-批量处理和调用存储过程

    一.命名查询 HQL语句混杂在代码之间将破坏代码的可读性 Hibernate允许在映射配置文件中定义字符串形式的查询语句,这种查询方式称为命名查询 二.建立数据表和持久化类 建立数据表 create ...

  3. less 命令(转)

    原文:http://www.cnblogs.com/peida/archive/2012/11/05/2754477.html less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux ...

  4. JSP的页面连接和提交方式(web基础学习笔记六)

    一.GET请求新页面 1.1.超链接请求新页面 <!-- 超链接到page2 --> <a href="page2.jsp">链接到page2</a& ...

  5. Flume wasn't able to parse timestamp header

    来自:http://caiguangguang.blog.51cto.com/1652935/1384187 flume bucketpath的bug一例 测试的配置文件: 1 2 3 4 5 6 7 ...

  6. Android自己定义控件:进度条的四种实现方式

    前三种实现方式代码出自: http://stormzhang.com/openandroid/2013/11/15/android-custom-loading/ (源代码下载)http://down ...

  7. Windows 无法启动MongoDB服务 错误1067:进程意外终止

    1:Windows 无法启动MongoDB服务 错误1067:进程意外终止 2:解决方法: 进入MongoDB安装目录\data\将此文件夹下的mongod.lock删除(网友提供解决方案,实验之后貌 ...

  8. bg和fg命令

    linux提供的fg和bg命令,可以让我们轻松调度正在运行的任务   假如你发现前天运行的一个程序需要很长的时间,但是需要干前天的事情,你就可以用ctrl-z挂起这个程序,然后可以看到系统的提示: [ ...

  9. 光驱在资源管理器显示黄色感叹号的解决方法BIOS内有 系统下没有

    1. 点开“开始”-运行regedit.exe,进入注册表编辑器,到左边的项目栏里找到HKEY_LOCAL_MACHINE\SYSTEM \CurrentControlSet\Control\Clas ...

  10. [TODO]com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method

    异常信息如下: 2018-10-30 20:00:50.230 ERROR java.util.concurrent.ExecutionException: com.alibaba.dubbo.rpc ...