天天看點

Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

Canvas之畫布操作

内容來自:安卓自定義View進階-Canvas之畫布操作

基本操作

位移

translate是坐标系的移動,位移是基于目前位置移動,而不是每次基于螢幕左上角的(0,0)點移動

// 繪制矩形
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(new Rect(0, 0, 200, 200), mPaint);

        // 在坐标原點繪制一個黑色圓形
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.translate(200, 200);
        canvas.drawCircle(100, 100, 100, mPaint);

        // 在坐标原點繪制一個藍色圓形
        mPaint.setColor(Color.BLUE);
        canvas.translate(200,200);
        canvas.drawCircle(0,0,100,mPaint);

           
Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

縮放(scale)

縮放提供了兩個方法,如下:

public void scale (float sx, float sy)

public final void scale (float sx, float sy, float px, float py)
           

縮放的中心預設為坐标原點,而縮放中心軸就是坐标軸,第二個方法的

px

py

,用來控制縮放中心位置

// 将坐标系原點移動到畫布正中心
canvas.translate(mWidth / 2, mHeight / 2);

RectF rect = new RectF(0,-400,400,0);   // 矩形區域

mPaint.setColor(Color.BLACK);           // 繪制黑色矩形
canvas.drawRect(rect,mPaint);

canvas.scale(0.5f,0.5f);                // 畫布縮放

mPaint.setColor(Color.BLUE);            // 繪制藍色矩形
canvas.drawRect(rect,mPaint);
           
Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

使用第二種方法讓縮放中心位置稍微改變一下,如下:

// 将坐标系原點移動到畫布正中心
canvas.translate(mWidth / 2, mHeight / 2);

RectF rect = new RectF(0,-400,400,0);   // 矩形區域

mPaint.setColor(Color.BLACK);           // 繪制黑色矩形
canvas.drawRect(rect,mPaint);

canvas.scale(0.5f,0.5f,200,0);          // 畫布縮放  <-- 縮放中心向右偏移了200個機關

mPaint.setColor(Color.BLUE);            // 繪制藍色矩形
canvas.drawRect(rect,mPaint);
           
Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

當縮放比例為負數的時候會根據縮放中心軸進行翻轉

// 将坐标系原點移動到畫布正中心
canvas.translate(mWidth / 2, mHeight / 2);

RectF rect = new RectF(0,-400,400,0);   // 矩形區域

mPaint.setColor(Color.BLACK);           // 繪制黑色矩形
canvas.drawRect(rect,mPaint);


canvas.scale(-0.5f,-0.5f);          // 畫布縮放

mPaint.setColor(Color.BLUE);            // 繪制藍色矩形
canvas.drawRect(rect,mPaint);
           
Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

和位移(translate)一樣,縮放也是可以疊加的,如下的例子:

// 将坐标系原點移動到畫布正中心
        canvas.translate(mWidth / 2, mHeight / 2);

        RectF rect = new RectF(-400,-400,400,400);

        for (int i = 0; i < 20; i++) {
            canvas.scale(0.9f, 0.9f);
            canvas.drawRect(rect, mPaint);
        }
           
Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

旋轉

旋轉提供了兩種方法:

public void rotate (float degrees)

public final void rotate (float degrees, float px, float py)
           

第二種方法多出來的兩個參數依舊是控制旋轉中心點的

預設的旋轉中心依舊是坐标原點:

// 将坐标系原點移動到畫布正中心
canvas.translate(mWidth / 2, mHeight / 2);

RectF rect = new RectF(0,-400,400,0);   // 矩形區域

mPaint.setColor(Color.BLACK);           // 繪制黑色矩形
canvas.drawRect(rect,mPaint);

canvas.rotate(180);                     // 旋轉180度 <-- 預設旋轉中心為原點

mPaint.setColor(Color.BLUE);            // 繪制藍色矩形
canvas.drawRect(rect,mPaint);
           
Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

改變旋轉中心位置:

// 将坐标系原點移動到畫布正中心
canvas.translate(mWidth / 2, mHeight / 2);

RectF rect = new RectF(0,-400,400,0);   // 矩形區域

mPaint.setColor(Color.BLACK);           // 繪制黑色矩形
canvas.drawRect(rect,mPaint);

canvas.rotate(180,200,0);               // 旋轉180度 <-- 旋轉中心向右偏移200個機關

mPaint.setColor(Color.BLUE);            // 繪制藍色矩形
canvas.drawRect(rect,mPaint);
           
Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

同樣旋轉也可以疊加

// 将坐标系原點移動到畫布正中心
canvas.translate(mWidth / 2, mHeight / 2);

canvas.drawCircle(0,0,400,mPaint);          // 繪制兩個圓形
canvas.drawCircle(0,0,380,mPaint);

for (int i=0; i<=360; i+=10){               // 繪制圓形之間的連接配接線
   canvas.drawLine(0,380,0,400,mPaint);
   canvas.rotate(10);
}
           
Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

skew

skew隻提供了一種方法

  • sx

    - 将畫布在

    x

    方向上傾斜相應的角度,sx傾斜角度的

    tan

  • sy

    - 将畫布在

    y

    軸方向上傾斜相應的角度,sy為傾斜角度的

    tan

// 将坐标系原點移動到畫布正中心
canvas.translate(mWidth / 2, mHeight / 2);

RectF rect = new RectF(0,0,200,200);   // 矩形區域

mPaint.setColor(Color.BLACK);           // 繪制黑色矩形
canvas.drawRect(rect,mPaint);

canvas.skew(1,0);                       // 水準錯切 <- 45度

mPaint.setColor(Color.BLUE);            // 繪制藍色矩形
canvas.drawRect(rect,mPaint);
           
Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

save和restore

我的了解,類似于iOS的

CGContextSaveGState

CGContextRestoreGState

相關API 簡介
save 把目前的畫布的狀态進行儲存,然後放入特定的棧中
saveLayerXxx 建立一個圖層,并放入特定的棧中
restore 把棧中最頂層的畫布狀态取出來,并按照這個狀态恢複目前的畫布
restoreToCount 彈出指定位置及其以上所有的狀态,并按照指定位置的狀态進行恢複
getSaveCount 擷取棧中内容的數量(即儲存次數)

狀态棧

狀态棧可以存儲畫布狀态和圖層狀态

Android自定義View學習四---Canvas畫布操作Canvas之畫布操作

save

save 有兩種方法:

// 儲存全部狀态
public int save ()

// 根據saveFlags參數儲存一部分狀态
public int save (int saveFlags)
           

可以看到第二種方法比第一種多了一個saveFlags參數,使用這個參數可以隻儲存一部分狀态,更加靈活。

saveFlags

參數,參見下表

名稱 簡介
ALL_SAVE_FLAG 預設,儲存全部狀态
CLIP_SAVE_FLAG 儲存剪輯區
CLIP_TO_LAYER_SAVE_FLAG 剪裁區作為圖層儲存
FULL_COLOR_LAYER_SAVE_FLAG 儲存圖層的全部色彩通道
HAS_ALPHA_LAYER_SAVE_FLAG 儲存圖層的alpha(不透明度)通道
MATRIX_SAVE_FLAG 儲存Matrix資訊( translate, rotate, scale, skew)

常用格式

save();      //儲存狀态
...          //具體操作
restore();   //復原到之前的狀态