1. 程式人生 > >自定義控制元件(二)Paint,Canvas 基礎用法

自定義控制元件(二)Paint,Canvas 基礎用法

本篇部落格繼續學習 Paint 和 Canvas 的基礎用法,上一篇部落格學習了基礎API使用( 基礎幾何圖形,Path 路徑 ),接下來學習 繪製文字繪製圖片
上一篇文章,沒看的有必要先了解一下:
自定義控制元件(一)Paint,Canvas 基礎用法 - Path函式大全,Canvas繪製基本幾何圖形

canvas 繪製 圖片Bitmap

drawBitmap
void drawBitmap(Bitmap bitmap, float left, float top, Paint paint)

引數
float left:距離控制元件左邊緣距離 類似起始座標X
float top:距離控制元件上邊緣距離 類似起始座標Y

這個函式很簡單,直接指定 top ,left 值,將整個圖片繪製出來

    Paint mPaint = new Paint();

    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_man);
    canvas.drawBitmap(bitmap, 50, 50, mPaint);

這裡寫圖片描述

void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)

引數
Rect src:對原圖片的裁剪區域
RectF dst:將(裁剪完的)原圖片繪製到View控制元件上的區域

第2個引數:需要將圖片哪個區域進行裁剪,如果傳 null 或者 bitmap.getWidth/bitmap.getHeight 表示不裁剪,將原圖完整繪製
第3個引數:處理後的圖片需要繪製到View控制元件上的哪個區域,圖片小於指定區域-放大;圖片大於指定區域-縮小

    Paint mPaint = new Paint();
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_man);
    canvas.drawBitmap(bitmap, null, new RectF(0, 0, getWidth() / 2, getHeight() / 2), mPaint);

獲取一張圖片,將原圖片繪製在 new RectF(0, 0, getWidth() / 2, getHeight() / 2) View寬高一半的矩形區域裡

這裡寫圖片描述

    Paint mPaint = new Paint();
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_man);
    canvas.drawBitmap(bitmap, new Rect(50, 50, 100, 100), new RectF(0, 0, getWidth() / 2, getHeight() / 2), mPaint);

獲取一張圖片,在原圖片上擷取內容 new Rect(50, 50, 100, 100) ,繪製在View寬高一半的矩形區域裡

這裡寫圖片描述 這裡寫圖片描述

Matrix
void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)

引數
Matrix matrix:矩陣 最根本的作用就是座標轉換
這是一個大學問啊,涉及到數學,就單單Android的Matrix單獨一篇博文都說不完,這裡先忽略不是重點可以檢視Android Matrix

基本變換有4種:
- 平移(Translate)
- 縮放(Scale)
- 旋轉(Rotate)
- 傾斜(Skew)

boolean postScale(float sx, float sy)
boolean postScale(float sx, float sy, float px, float py)

引數
float sx:X軸縮放倍數 大於1放大,小於1縮小 小於0對稱變化(鏡子,倒影)
float sy:Y軸縮放倍數 同上
float px:縮放的中心點X 預設原點(0,0)
float py:縮放的中心點Y 同上

    Paint mPaint = new Paint();
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_man);
    Matrix matrix = new Matrix();
    matrix.postScale(2, 2);
    //放大2倍效果
    canvas.drawBitmap(bitmap, matrix, mPaint);
    //繪製原圖
    canvas.drawBitmap(bitmap, 0, 0, mPaint);

將影象放大2倍繪製,後面再繪製原圖做對比

這裡寫圖片描述

boolean postTranslate(float dx, float dy)

引數
float dx:X軸位移數值
float dy:Y值位移數值

    Paint mPaint = new Paint();
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_man);
    //繪製原圖
    canvas.drawBitmap(bitmap, 0, 0, mPaint);
    //平移圖片
    Matrix matrix = new Matrix();
    matrix.postTranslate(bitmap.getWidth(), bitmap.getHeight());
    canvas.drawBitmap(bitmap, matrix, mPaint);

這裡寫圖片描述

boolean postRotate(float degrees)
boolean postRotate(float degrees, float px, float py)

引數
float degrees:旋轉角度
float px:旋轉中心X座標 預設(0,0)
float py:旋轉中心Y座標 預設(0,0)

    Paint mPaint = new Paint();
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_man);
    //繪製原圖
    canvas.drawBitmap(bitmap, 0, 0, mPaint);
    //繪製邊框區分原圖
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(5);
    canvas.drawRect(new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()), mPaint);
    //旋轉圖片
    Matrix matrix = new Matrix();
    matrix.postRotate(45, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
    canvas.drawBitmap(bitmap, matrix, mPaint);

程式碼很簡單,先繪製一張原圖,然後重新設定畫筆,繪製邊框用來區分底部的原圖,最後繪製旋轉後的圖片

這裡寫圖片描述

boolean postSkew(float kx, float ky)
boolean postSkew(float kx, float ky, float px, float py)

引數
float kx:X軸傾斜值 大於0向左傾斜,小於0向右傾斜
float ky:Y軸傾斜值 大於0向下傾斜,小於0向上傾斜
float px:傾斜依據點X,預設(0,0)左上角
float py:傾斜依據點Y,預設(0,0)左上角

    Paint mPaint = new Paint();
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_man);
    //繪製原圖
    canvas.drawBitmap(bitmap, 0, 0, mPaint);
    //繪製邊框區分原圖
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(5);
    canvas.drawRect(new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()), mPaint);
    //傾斜圖片
    Matrix matrix = new Matrix();
    matrix.postSkew(-0.5f, 0, 0, bitmap.getHeight());
    canvas.drawBitmap(bitmap, matrix, mPaint);

繪製一張原圖,加上邊框區分,變換矩陣,以圖片左下角為依據點,只傾斜X軸 效果如下
這裡寫圖片描述

canvas 繪製 文字

文字繪製是自定義控制元件中最常用的功能,這裡分兩部分講 paint 和 canvas

paint 畫筆屬性也可以改變很多文字的屬性和樣式 ( 摘自網路 )

    Paint paint=new Paint();
    paint.setColor(Color.RED);  //設定畫筆顏色

    //普通設定
    paint.setStrokeWidth (5);//設定畫筆寬度
    paint.setAntiAlias(true); //指定是否使用抗鋸齒功能
    paint.setStyle(Paint.Style.FILL);//繪圖樣式,對於設文字和幾何圖形都有效
    paint.setTextAlign(Paint.Align.CENTER);//設定文字對齊方式,取值:align.CENTER、align.LEFT或align.RIGHT
    paint.setTextSize(12);//設定文字大小

    //樣式設定
    paint.setFakeBoldText(true);//設定是否為粗體文字
    paint.setUnderlineText(true);//設定下劃線
    paint.setTextSkewX((float) -0.25);//設定字型水平傾斜度,普通斜體字是-0.25
    paint.setStrikeThruText(true);//設定帶有刪除線效果

    //其它設定
    paint.setTextScaleX(2);//只會將水平方向拉伸,高度不會變

這個是畫筆 paint 相關的 api 都比較簡單,多用記住就好了,就不一一貼效果圖了(好多,懶了),其中設定下劃線 setUnderlineText ,刪除線 setStrikeThruText 應該會用的比較多。

繪製文字drawText

void drawText(String text, float x, float y, Paint paint)

引數
String text:目標文字
float x:繪製原點 x 座標
float y:繪製原點 y 座標

    Paint mPaint = new Paint();
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(2);
    mPaint.setTextSize(60);

    //垂直方向中線
    canvas.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2, mPaint);

    mPaint.setColor(Color.RED);

    String text = "Loading";
    float x = getWidth() / 2;//寬度一半
    float y = getHeight() / 2;//高度一半
    canvas.drawText(text, x, y, mPaint);

這段程式碼是在控制元件寬度1/2,高度1/2處開始繪製文字,中間新增一條中線作為輔助理解

這裡寫圖片描述

一般而言,(x,y)所代表的位置是所畫圖形對應的矩形的左上角點。通過上圖,可以看出我們實際畫出的效果並不是我們想象的那樣,因為在 drawText 這個 y 非常特殊,它代表的是基線的位置

那麼問題來了什麼是基線? 小時候我們寫拼音用的本子四線格,我們都是從第三行開始寫的,這一行就是基線。 (圖片來源於網路)

這裡寫圖片描述

其他函式

void drawText(char[] text, int index, int count, float x, float y, Paint paint)
void drawText(String text, int start, int end, float x, float y, Paint paint)
void drawText(CharSequence text, int start, int end, float x, float y, Paint paint)

引數
char[] text:字元陣列
int index:開始下標
int count:參與繪製的字元個數
int start:起始下標
int end:結束下標

這幾個函式比較簡單,常用來擷取字元或者字串,不再示例

根據路徑繪製文字 drawTextOnPath

void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)
void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)

引數
Path path:路徑 前面說過,參考前面
float hOffset:與路徑起始點的水平偏移距離
float vOffset:與路徑中心的垂直偏移量

    Paint mPaint = new Paint();
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(5);
    mPaint.setTextSize(50);

    Path path = new Path();
    path.addRect(100, 200, 300, 600, Path.Direction.CCW);//逆時針

    Path path2 = new Path();
    path2.addRect(600, 200, 800, 600, Path.Direction.CCW);//逆時針

    canvas.drawPath(path, mPaint);
    canvas.drawPath(path2, mPaint);

    mPaint.setColor(Color.BLACK);

    canvas.drawTextOnPath("幸福別等", path, 0, 0, mPaint);
    canvas.drawTextOnPath("幸福別等", path2, 100, 100, mPaint);

繪製第一個圓形路徑,然後根據原型路徑繪製文字,繪製第二個圓形路徑,設定偏移量,再根據路徑繪製文字。

這裡寫圖片描述

字型樣式設定(Typeface)

字型樣式設定,這個功能很常用,系統預設會有一個字型樣式,如果開發者想要設定文字字型,需要引入一個字型檔案,根據路徑獲取字型,然後設定 Typeface

建立

    Typeface    create(String familyName, int style) //直接通過指定字型名來載入系統中自帶的文字樣式
    Typeface    create(Typeface family, int style)     //通過其它Typeface變數來構建文字樣式
    Typeface    createFromAsset(AssetManager mgr, String path) //通過從Asset中獲取外部字型來顯示字型樣式
    Typeface    createFromFile(String path)//直接從路徑建立
    Typeface    createFromFile(File path)//從外部路徑來建立字型樣式
    Typeface    defaultFromStyle(int style)//建立預設字型

Style列舉值

Typeface.NORMAL  //正常體
Typeface.BOLD    //粗體
Typeface.ITALIC  //斜體
Typeface.BOLD_ITALIC //粗斜體

如果是自定義字型樣式,首先在 assets 下建一個資料夾,命名為 fonts,然後將字型檔案huakangshaonv.ttf 放入其中,網上可以下載各種各樣的字型

    Paint mPaint = new Paint();
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeWidth(5);
    mPaint.setTextSize(50);

    AssetManager assetManager = getResources().getAssets();//得到AssetManager
    Typeface typeface = Typeface.createFromAsset(assetManager, "fonts/huakangshaonv.ttf");//獲取字型
    mPaint.setTypeface(typeface);//設定字型樣式

    canvas.drawText("Ruffian-痞子 010101", 100, 100, mPaint);

這裡寫圖片描述

很簡單也和使用,很自然的我又要安利一下我的一個開源專案了,很輕便的一個TextView封裝,其中也用到了字型樣式設定 RTextView

好了基礎的用法就先到這裡吧,把這些基礎的學會了,基本的繪圖應該沒什麼問題,如果有,那就繼續博主的後續文章,會不斷更新自定義控制元件繪製方面的知識

由於都是基礎API的說明和示例,本人也是根據網路學習參考而來,寫作思路參考了 啟艦
很喜歡他對這種基礎API的說明方式,圖文並茂,深入淺出,如果寫作思路的參考造成了對 啟艦 的侵權,我將關閉相關部落格