標籤:
分類: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); } }}
【Android】21.2 Canvas和Paint