【Android】21.2 2D图形图像处理(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 - );
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)的更多相关文章
- 【Android】第21章 2D图形和动画
分类:C#.Android.VS2015: 创建日期:2016-03-19 一.简介 Android系统定义了一系列独立的图形处理类,其中,2D图形处理类分别位于以下命名空间: Android.Gra ...
- android学习笔记43——图形图像处理3——Path
Path类 Path类可以预先在View上将N个点连成一条“路径”,然后调用Canavas的drawPath(path,paint)即可沿着路径绘制图形. android还为路径绘制提供了PathEf ...
- android学习笔记42——图形图像处理2——绘图
绘图 android的绘图应该继承View组件,并重写onDraw(Canvas canvas)方法即可. 重写onDraw(Canvas canvas)方法时涉及一个绘图API:Canvas,Can ...
- android学习笔记41——图形图像处理1
图像图像处理 ImageView:用于显示普通静态图片: AnimationDrawable:用于开发逐帧动画: Animation:用于对普通图片使用补间动画: Bitmap.BitmapFacto ...
- Android使用学习之画图(Canvas,Paint)与手势感应及其应用(乒乓球小游戏)
作为一个没有学习Android的菜鸟,近期一直在工作之外努力地学习的Android的使用. 这周看了下Android的画图.主要是Canvas,Paint等,感觉须要实践下.下午正好有空,就想整一个乒 ...
- 自定义View(4)Canvas和Paint常用绘制函数
画布Canvas 在Android下进行2D绘图需要Canvas类的支持,它位于"android.graphics.Canvas"包下,直译过来为画布的意思,用于完成在View上的 ...
- HTML5图形图像处理技术研究
摘要:图形图像处理平台大部分是传统的C/S架构的桌面应用程序,维护困难,共享性差,而B/S架构的Web程序具有易维护.易共享的优点.本文研究了基于HTML5的Web图形图像处理技术,用HTML5实现了 ...
- 【转】android Graphics(四):canvas变换与操作
android Graphics(四):canvas变换与操作 分类: 5.andriod开发2014-09-05 15:05 5877人阅读 评论(18) 收藏 举报 目录(?)[+] 前言 ...
- 图形绘制 Canvas Paint Path 详解
图形绘制简介 Android中使用图形处理引擎,2D部分是android SDK内部自己提供,3D部分是用Open GL ES 1.0.大部分2D使用的api都在android.grap ...
随机推荐
- eclipse在search的时候,通过search打开的页面会覆盖之前打开的页面
eclipse在search的时候,通过search打开的页面会覆盖之前打开的页面,如果不想覆盖的话,可以这么设置: Window->Preferences->General->Se ...
- Throwing cards away I uva1594
Throwing cards away I Given is an ordered deck of n cards numbered 1 to n with card 1 at the t ...
- Oracle使用——PLSQL的中文乱码显示全是问号
问题 这两天刚将PLSQL与Oracle配置好,但是在PLSQL中插入数据时.出现一个问题,PLSQL中的表里无法显示中文,中文无法保存.无法输出.中文在表中显示问号.如图: 原因 经过一番查证,发现 ...
- Linux系统中用stat命令查看文件的三个时间属性
在Linux中,没有文件创建时间的概念.只有文件的访问时间.修改时间.状态改变时间.也就是说无法知道文件的创建时间. [root@rhel7 yum.repos.d]# stat cdrom.repo ...
- 关于iOS 类扩展Extension的进一步理解
很多人可能会问 iOS的分类和扩展的区别,网上很多的讲解,但是一般都是分类讲的多,而这也是我们平常比较常用的知识:但是,对于扩展,总觉得理解的朦朦胧胧,不够透彻. 这里就讲一下我自己的理解,但是这个 ...
- windows系统定时重启自定义exe程序
工作需要, Windows系统定时重启自定义exe程序. 写了如下程序, 按照说明(readme.txt)修改批处理文件中的四个参数即可: 1.readme.txt 第一个参数:进程名(不用带exe) ...
- HDUOJ-----1556Color the ball
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- linux常见面试题及答案
1. 在Linux系统中,以文件方式访问设备. 2. Linux内核引导时,从文件/etc/fstab中读取要加载的文件系统. 3. Linux文件系统中每个文件用i字节来标识. 4. 全部磁盘块由四 ...
- windows服务器开启openssl
windows服务器默认是没有开启openss的php扩展支持,不过一般服务器里面默认都已经安装了这个功能.自己开启一下就好,今天在安装某程序的时候,需要用到openss的支持,才发现windows服 ...
- Redis下载和安装
原文地址:https://redis.io/download Download Redis uses a standard practice for its versioning: major.min ...