Android 2D Graphics學習(二)、Canvas篇1、Canvas基本使用
Android官方文件對Canvas的簡介很好的介紹了Canvas的使用:
- The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels,
- a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap),
- and a paint (to describe the colors and styles for the drawing).
1、一個用來儲存畫素的Bitmap
2、一個Canvas在Bitmap上進行繪製操作
3、繪製的東西
4、繪製的畫筆Paint
1、如何獲得一個Canvas物件。
Canvas物件的獲取方式有三種:
第一種我們通過重寫View.onDraw方法,View中的Canvas物件會被當做引數傳遞過來,我們操作這個Canvas,效果會直接反應在View中。
第二種就是當你想自己建立一個Canvas物件。從上面的基本要素可以明白,一個Canvas物件一定是結合了一個Bitmap物件的。所以一定要為一個Canvas物件設定一個Bitmap物件。
- //得到一個Bitmap物件,當然也可以使用別的方式得到。但是要注意,改bitmap一定要是mutable(異變的)
- Bitmap b = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(b);
- /*先new一個Canvas物件,在呼叫setBitmap方法,一樣的效果
- * Canvas c = new Canvas();
- * c.setBitmap(b);
- */
2、Canvas能繪製什麼
Canvas類提供了一系列的draw...方法,從這些方法的名字就可以知道Canvas可以繪製的物件。
1、填充
- public void drawARGB(int a, int r, int g, int b)
- public void drawColor(int color)
- public void drawRGB(int r, int g, int b)
- public void drawColor(int color, PorterDuff.Mode mode)
- public void drawPaint(Paint paint)
同理,Canvas也可以使用畫筆去填充整個Bitmap,同樣和填充顏色一樣受限制於clip的範圍,API中明確指出(This is equivalent (but faster) to drawing an
infinitely large rectangle with the specified paint)這相當於用指定的畫筆畫一個更大範圍的矩形,但是速度更快。
其實在Skia內部,填充呼叫的都是drawPaint方法的。
2、繪製幾何影象
canvas.drawArc (扇形)
canvas.drawCircle(圓)
canvas.drawOval(橢圓)
canvas.drawLine(線)
canvas.drawPoint(點)
canvas.drawRect(矩形)
canvas.drawRoundRect(圓角矩形)
canvas.drawVertices(頂點)
cnavas.drawPath(路徑)
3、繪製圖片
canvas.drawBitmap (點陣圖)
canvas.drawPicture (圖片)
4、文字
canvas.drawText
上面列舉的是Canvas所能繪製的基本內容,在實際使用中,可以使用各種過濾或者過度模式,或者其他手段,來達到繪製各種效果。
3、Canvas的變換
如果只是那些簡單的draw...方法,那麼canvas的功能就太單調了。Canvas還提供了一系列位置轉換的方法:rorate、scale、translate、skew(扭曲)等。
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.translate(100, 100);
- canvas.drawColor(Color.RED);//可以看到,整個螢幕依然填充為紅色
- canvas.drawRect(new Rect(-100, -100, 0, 0), new Paint());//縮放了
- canvas.scale(0.5f, 0.5f);
- canvas.drawRect(new Rect(0, 0, 100, 100), new Paint());
- canvas.translate(200, 0);
- canvas.rotate(30);
- canvas.drawRect(new Rect(0, 0, 100, 100), new Paint());//旋轉了
- canvas.translate(200, 0);
- canvas.skew(.5f, .5f);//扭曲了
- canvas.drawRect(new Rect(0, 0, 100, 100), new Paint());
- // canvas.setMatrix(matrix);//Matrix的使用在後面在是。
- }
Canvas雖然內部保持了一個Bitmap,但是它本身並不代表那個Bitmap,而更像是一個圖層。我們對這個圖層的平移旋轉和縮放等等操作,並不影響內部的Bitmap,僅僅是改變了該圖層相對於內部Bitmap 的座標位置、比例和方向而已。
4、Canvas的儲存和回滾
為了方便一些轉換操作,Canvas還提供了儲存和回滾屬性的方法(save和restore),比如你可以先儲存目前畫紙的位置(save),然後旋轉90度,向下移動100畫素後畫一些圖形,畫完後呼叫restore方法返回到剛才儲存的位置。
Canvas提供的該功能的API如下:
- /**
- * 儲存當前的matrix和clip到私有的棧中(Skia內部實現)。任何matrix變換和clip操作都會在呼叫restore的時候還原。
- * @return 返回值可以傳入到restoreToCount()方法,以返回到某個save狀態之前。
- */
- public native int save();
- /**
- * 傳入一個標誌,來表示當restore 的時候,哪些引數需要還原。該引數定義在Canvas中,參照下面。
- * save()方法預設的是還原matrix和clip,但是可以使用這個方法指定哪些需要還原。並且只有指定matrix和clip才有效,其餘的幾個引數是
- * 用於saveLayer()和saveLayerAlpha()方法 的。
- */
- public native int save(int saveFlags);
- /**
- * 回到上一個save呼叫之前的狀態,如果restore呼叫的次數大於save方法,會出錯。
- */
- public native void restore();
- /**
- * 返回棧中儲存的狀態,值等譯 save()呼叫次數-restore()呼叫次數
- */
- public native int getSaveCount();
- /**
- * 回到任何一個save()方法呼叫之前的狀態
- */
- public native void restoreToCount(int saveCount);
- /**saveFlags的引數*/
- public static final int MATRIX_SAVE_FLAG = 0x01;//需要還原Matrix
- public static final int CLIP_SAVE_FLAG = 0x02;//需要還原Clip
- /**下面三個引數在saveLayer的時候使用,具體作用,沒有搞明白*/
- public static final int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04;
- public static final int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;
- public static final int CLIP_TO_LAYER_SAVE_FLAG = 0x10;
- public static final int ALL_SAVE_FLAG = 0x1F; //還原所有
- /*關於saveLayer的具體flags還不大明白它的含義,具體怎麼使用在下面例子中*/
- public int saveLayer(RectF bounds, Paint paint, int saveFlags)
- public int saveLayer(float left, float top, float right, float bottom,
- Paint paint, int saveFlags)
- public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags)
- public int saveLayerAlpha(float left, float top, float right, float bottom,
- int alpha, int saveFlags)
saveLayer
Canvas 在一般的情況下可以看作是一張畫布,所有的繪圖操作如drawBitmap, drawCircle都發生在這張畫布上,這張畫板還定義了一些屬性比如Matrix,顏色等等。但是如果需要實現一些相對複雜的繪圖操作,比如多層動畫,地圖(地圖可以有多個地圖層疊加而成,比如:政區層,道路層,興趣點層)。Canvas提供了圖層(Layer)支援,預設情況可以看作是隻有一個圖層Layer。如果需要按層次來繪圖,Android的Canvas可以使用SaveLayerXXX, Restore 來建立一些中間層,對於這些Layer是按照“棧結構“來管理的:
建立一個新的Layer到“棧”中,可以使用saveLayer, savaLayerAlpha, 從“棧”中推出一個Layer,可以使用restore,restoreToCount。但Layer入棧時,後續的DrawXXX操作都發生在這個Layer上,而Layer退棧時,就會把本層繪製的影象“繪製”到上層或是Canvas上,在複製Layer到Canvas上時,可以指定Layer的透明度(Layer),這是在建立Layer時指定的:public int saveLayerAlpha(RectF bounds,
int alpha, int saveFlags)本例Layers 介紹了圖層的基本用法:Canvas可以看做是由兩個圖層(Layer)構成的,為了更好的說明問題,我們將程式碼稍微修改一下,預設圖層繪製一個紅色的圓,在新的圖層畫一個藍色的圓,新圖層的透明度為0×88。
- public class Layers extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(new SampleView(this));
- }
- private static class SampleView extends View {
- private static final int LAYER_FLAGS = Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG
- | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG
- | Canvas.CLIP_TO_LAYER_SAVE_FLAG;
- private Paint mPaint;
- public SampleView(Context context) {
- super(context);
- setFocusable(true);
- mPaint = new Paint();
- mPaint.setAntiAlias(true);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.drawColor(Color.WHITE);
- canvas.translate(10, 10);
- mPaint.setColor(Color.RED);
- canvas.drawCircle(75, 75, 75, mPaint);
- canvas.saveLayerAlpha(0, 0, 200, 200, 0x88, LAYER_FLAGS);
- mPaint.setColor(Color.BLUE);
- canvas.drawCircle(125, 125, 75, mPaint);
- canvas.restore();
- }
- }
- }
相關文章
- Android 2D Graphics學習(二)、Canvas篇2、Canvas裁剪和Region、RegionIteratorAndroidCanvas
- Android 2D Graphics學習(一)、android.graphics介紹Android
- canvas學習筆記-2d畫布基礎Canvas筆記
- canvas 2d toDataURLCanvas
- Flutter Canvas學習之繪圖篇FlutterCanvas繪圖
- HTML5 快速學習二 CanvasHTMLCanvas
- Bitmap回收—Canvas: trying to use a recycled bitmap android.graphicsCanvasAndroid
- canvas學習(一)Canvas
- Android的Paint、Canvas和Path基本使用總結AndroidAICanvas
- canvas複習總結(二)Canvas
- Android自定義View-Canvas基本操作AndroidViewCanvas
- 二維CANVAS基本語法(圖片Image)Canvas
- Canvas學習筆記(一)Canvas筆記
- html5 canvas學習--操作與使用影象HTMLCanvas
- Canvas 都坐下,基本操作Canvas
- 使用JavaScript和Canvas開發遊戲(二)JavaScriptCanvas開發遊戲
- Qt學習第二篇(基本小元件的使用)QT元件
- Canvas&Paint 知識梳理(1) Canvas 基礎CanvasAI
- Android自定義View工具:Paint&Canvas(二)AndroidViewAICanvas
- 學習canvas基礎的總結Canvas
- canvas繪製圖片drawImage學習Canvas
- android canvas\paint\path簡單使用(自定義view必學)AndroidCanvasAIView
- Android: Bitmap/Canvas/DrawableAndroidCanvas
- Android 繪圖——CanvasAndroid繪圖Canvas
- Android自定義View之Canvas的使用AndroidViewCanvas
- 學習HTML5 Canvas這一篇文章就夠了HTMLCanvas
- canvas動畫教程-1 引言Canvas動畫
- Canvas 最佳實踐(效能篇)Canvas
- html5 canvas學習--繪製文字HTMLCanvas
- canvas學習之API整理筆記(一)CanvasAPI筆記
- canvas學習筆記:小公式大樂趣Canvas筆記公式
- 【練習】canvas——flappyBirdCanvasAPP
- NIO學習二、NIO的基本使用
- 《WebGL程式設計指南》學習筆記——2.使用< canvas >元素Web程式設計筆記Canvas
- android基礎學習-android篇day17-Android Fragment(碎片)基本使用AndroidFragment
- 2019.1.21 canvas學習小計Canvas
- 自定義View相關學習(一) (SlantedTextView ,canvas)TextViewCanvas
- Android 利用 Canvas 畫畫板AndroidCanvas