1. 程式人生 > >Android繪圖基礎之Canvas & Paint & Rect & RectF

Android繪圖基礎之Canvas & Paint & Rect & RectF

Rect & RectF

RectF和Rect都表示的是一個矩形的區域,他們的構造方法類似!

不同的是,Rect 的精度是integer,RectF 的精度是float !!

public Rect(int left, int top, int right, int bottom) {
        this.left = left;
        this.top = top;
        this.right = right;
        this.bottom = bottom;
    }
public RectF(float left, float
top, float right, float bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; }

在RectF.java 中,有這樣兩個函式

public void round(Rect dst) {
        dst.set(FastMath.round(left), FastMath.round(top),
                FastMath.round(right
), FastMath.round(bottom)); }
public void roundOut(Rect dst) {
        dst.set((int) Math.floor(left), (int) Math.floor(top),
                (int) Math.ceil(right), (int) Math.ceil(bottom));
    }

目的就是將 RectF 轉成 Rect

Canvas

Canvas – 畫布

canvas 裡的方法基本可以分為這麼幾類:

  • save、restore 等與層的儲存和回滾相關的方法;

  • scale、rotate、clipxxx 等對畫布進行操作的方法;

  • drawxxx 等一系列繪圖相關的方法;

想要畫圖案,就得需要用到畫布(Canvas)、畫筆(Paint)、路徑(Path)、填充(Shader)。

想要對圖案做變形處理,就得用到Matrix(矩陣)

Paint

Paint就是畫布上畫圖用的畫筆!

提供了畫筆的顏色、透明度、大小、筆刷的風格等屬性!

Paint常用屬性如下:

  • setARGB/setColor 設定顏色

  • setAlpha 設定透明度

  • setAntiAlias 設定是否抗鋸齒

  • setShader 設定畫筆的填充效果

  • setShaderLayer 設定陰影

  • setStyle 設定畫筆風格(填充模式)

    • Paint.Style.FILL :填充內部

    • Paint.Style.FILL_AND_STROKE :填充內部和描邊

    • Paint.Style.STROKE :僅描邊

  • setStrokeWidth 設定邊框的寬度

  • setStrokeCap() 設定線冒樣式

    • Paint.Cap.ROUND : 圓形線冒

    • Paint.Cap.SQUARE:方形線冒

    • Paint.Cap.BUTT:無線冒

  • setStrokeJoin() 設定線段連線處樣式

    • Paint.Join.MITER:結合處為銳角

    • Paint.Join.Round:結合處為圓弧

    • Paint.Join.BEVEL:結合處為直線)

  • setStrokeMiter(float miter) :設定筆畫的傾斜度

  • setPathEffect(PathEffect effect) :設定路徑樣式

  • setXfermode(Xfermode xfermode):設定Xfermode樣式

  • setTextSize():設定文字大小

  • setTextAlign(Align align) : 設定文字排列方式

  • setTextScaleX(float scaleX):設定文字X軸方向縮放比例,預設值是1.0,大於1.0表示放大,小於1.0表示縮小

  • setTextSkewX(float skewX):設定文字X軸錯切

Point

Canvas繪製點有三個過載的函式:

  • drawPoint(float x, float y, @NonNull Paint paint)

  • drawPoints(@Size(multiple=2) @NonNull float[] pts, @NonNull Paint paint)

  • drawPoints(@Size(multiple=2) float[] pts, int offset, int count, @NonNull Paint paint)

paint.setStrokeWidth(50);
paint.setColor(Color.BLACK);
canvas.drawPoint(200, 200, paint); // 點的x、y座標, 畫筆
private float[] points = new float[]{10, 10, 100, 10, 200, 100};
canvas.drawPoints(points, paint); // 座標的陣列 + 畫筆
// 陣列中多餘(不是2的倍數時)系統忽略掉!
// 第二個引數表示陣列偏移幾位
// 第三個引數表示使用陣列中的幾位,最好是2的倍數!
canvas.drawPoints(points, 1, 4, paint); 

這裡寫圖片描述

Line

Canvas繪製線有三個過載的函式

  • drawLine(float startX, float startY, float stopX, float stopY, @NonNull Paint paint)

  • drawLines(@Size(multiple=4) @NonNull float[] pts, int offset, int count, @NonNull Paint paint)

  • drawLines(@Size(multiple=4) @NonNull float[] pts, @NonNull Paint paint)

canvas.drawLine(100, 100, 200, 200, paint); // 起點和終點,加上畫筆
private float[] lines = new float[]{0, 0, 100, 0, 0, 0, 100, 100, 0, 0, 0, 100};
canvas.drawLines(lines, paint); // 繪製多條線

繪製多條線的函式,第一個引數是一個數組,而陣列的長度需要時4的倍數!

@Size(multiple=4) @NonNull float[] pts

如果不是4的倍數,繪製的時候只會去前面是4的倍數的組,後面的將被捨棄!

三個引數的函式:

canvas.drawLines(lines, 2, 8, paint);

第一個引數同樣是點(x, y)的集合,第二個引數表示“偏移量“,就是需要跳過陣列前面一定的值,從中間某個位置開始取值;第三個引數count, 表示要取出值的個數,由於要畫線,所以count儘量是4的倍數!

兩個引數的函式的效果圖:

這裡寫圖片描述

Arc

Canvas中關於畫圓弧也有2個過載的函式:

  • drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint) //

  • drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint)

畫圓弧依託於oval(橢圓)!

RectF 或者Rect 表示一個矩形區域,一個矩形區域對應著一個內接橢圓~

而圓弧正是橢圓上的一部分!

        paint.setColor(Color.GREEN);
        paint.setStrokeWidth(10);

        canvas.drawArc(rectF, 0, 90, true, paint); // startAngel 表示圓弧起始的角度,sweepAngle表示圓弧的角度(跨度),  useCenter 表示是否將中心包括在內,繪製成扇形!

        paint.setColor(Color.RED);
        canvas.drawArc(rectF, 90, 90, true, paint);

        paint.setColor(Color.BLUE);
        canvas.drawArc(rectF, 180, 90, true, paint);

        paint.setColor(Color.BLACK);
        canvas.drawArc(rectF, 270, 90, true, paint);

這裡寫圖片描述

        paint.setColor(Color.GREEN);
        canvas.drawArc(rectF, 0, 90, true, paint);

        paint.setColor(Color.RED);
        canvas.drawArc(rectF, 90, 90, false, paint); // 不包括中心點

        paint.setColor(Color.BLUE);
        canvas.drawArc(rectF, 180, 90, true, paint);

        paint.setColor(Color.BLACK);
        canvas.drawArc(rectF, 270, 90, false, paint); // 不包括中心點

這裡寫圖片描述

而8個引數的函式,前面四個引數分別是left, top, right, bottom!正好定義了一個RectF 矩形區域!

其實這兩個函式內部是有關聯的:

public void drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint) {
        drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint); // 將RectF拆開,呼叫8個引數的函式!
    }

舉例:

 canvas.drawArc(0, 0, 300, 300, 30, 90, true, paint);
        paint.setColor(Color.GRAY);
        canvas.drawArc(0, 0, 300, 300, 30, -90, true, paint);

這裡寫圖片描述

Circle

繪製圓形就需要一箇中心點座標(x, y),加一個半徑,和畫筆!

  • drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
canvas.drawCircle(200, 200, 100, paint);

這裡寫圖片描述

如果想畫一個圓環,就是中間不填充,改一下畫筆的填充模式即可!

paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(200, 200, 100, paint);

Oval

繪製橢圓就需要一個矩形區域!

  • drawOval(@NonNull RectF oval, @NonNull Paint paint)

  • drawOval(float left, float top, float right, float bottom, @NonNull Paint paint)

canvas.drawOval(rectF, paint);

paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
canvas.drawOval(150, 300, 700, 700, paint);

這裡寫圖片描述

Rect

繪製矩形

  • drawRect(float left, float top, float right, float bottom, @NonNull Paint paint)

  • drawRect(@NonNull Rect r, @NonNull Paint paint)

  • drawRect(@NonNull RectF rect, @NonNull Paint paint)

private Rect rect = new Rect(150, 150, 300, 500);
private RectF rectF = new RectF(100.5f, 100.5f, 400.5f, 600.0f);
canvas.drawRect(rect, paint);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(rectF, paint);
paint.setColor(Color.YELLOW);
canvas.drawRect(50.0f, 50.0f, 650.0f, 650.0f, paint);

這裡寫圖片描述

RoundRect

  • drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, @NonNull Paint paint)

  • drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint)

canvas.drawRoundRect(rectF, 30, 30, paint);

paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.YELLOW);
canvas.drawRoundRect(50.0f, 50.0f, 600.f, 300.f, 30, 30, paint);

這裡寫圖片描述

Text

  • drawText(@NonNull String text, float x, float y, @NonNull Paint paint)

  • drawText(@NonNull CharSequence text, int start, int end, float x, float y, @NonNull Paint paint)

  • drawText(@NonNull String text, int start, int end, float x, float y, @NonNull Paint paint)

  • drawTextOnPath(@NonNull char[] text, int index, int count, @NonNull Path path, float hOffset, float vOffset, @NonNull Paint paint)

  • drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,float vOffset, @NonNull Paint paint)

paint.setColor(Color.BLUE);
paint.setTextSize(40.0f);

canvas.drawText("黃河之水天上來\n奔流到海不復回", 0, 100, paint);

paint.setColor(Color.YELLOW);
paint.setTextSkewX(-0.5f); // X軸錯切
canvas.drawText("為天地立心,為生民立命", 2, 6, 0, 200, paint);

paint.setColor(Color.MAGENTA);
paint.setTextScaleX(1.5f); // X軸縮放
canvas.drawText(chars, 1, 5, 0, 300, paint);

paint.setColor(Color.BLACK);
paint.setTextSize(30.0f);
canvas.drawText(spannableString, 0, spannableString.length() - 1, 0, 400, paint);

path.addOval(rectF2, Path.Direction.CCW);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, paint);
paint.setColor(Color.RED);
paint.setTextSize(40.0f);
paint.setStyle(Paint.Style.FILL);
canvas.drawTextOnPath("大河向東流", path, 0, 50, paint);

這裡寫圖片描述

Bitmap

  • drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint)

  • drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull RectF dst, @Nullable Paint paint)

  • drawBitmap(@NonNull Bitmap bitmap, @Nullable Rect src, @NonNull Rect dst, @Nullable Paint paint)

  • drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint)

src 是指bitmap的區域,dst是指bitmap顯示在螢幕上的區域

private Matrix matrix = new Matrix();

matrix.postRotate(180.0f); // 旋轉180°
matrix.postTranslate(800, 1200);

bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.child);
canvas.drawBitmap(bitmap, 20, 20, null);
canvas.drawBitmap(bitmap, srcRect, dstRect, paint);
canvas.drawBitmap(bitmap, matrix, paint);

這裡寫圖片描述

關於Matrix,之後的blog會再詳細介紹!

Path

  • drawPath(@NonNull Path path, @NonNull Paint paint) // 路徑 + 畫筆
path.moveTo(50, 100);
path.lineTo(50, 300);
path.lineTo(100, 500);
path.lineTo(400, 500);
path.lineTo(300, 300);
path.lineTo(450, 50);
path.lineTo(200, 200);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, paint);

這裡寫圖片描述

相關推薦

Android繪圖基礎Canvas & Paint & Rect & RectF

Rect & RectF RectF和Rect都表示的是一個矩形的區域,他們的構造方法類似! 不同的是,Rect 的精度是integer,RectF 的精度是float !! public Rect(int left,

Android 自定義View繪圖工具類Canvas+Paint+Path(onDraw方法)基礎詳解

本章節講述三個繪圖工具類Canvas(畫布),Paint(畫筆),Path(路徑) 1.Canvas(畫布)相關方法詳解 1.1. 方法:Canvas() 作用:建立一個空的畫布,可以使

Android canvas繪圖基礎運動的時鐘

一、canvas繪製圖形 canvas可以繪製很多幾何圖形、文字等很多東西: 1. drawText 2. drawPoint 3. drawLine 4. drawRect 5. drawCircle 6. drawOval 7. drawA

Android 2D繪圖解析 CanvasPaint

【Android 2D繪圖解析】系列文章將全面介紹Android繪圖相關,這篇簡單介紹下如何利用Android API進行一些簡單圖形的繪製,繪圖的前提是需要繼承自View,然後重寫它的onDraw(Canvas canvas) 方法即可。 首先我們新建一個類繼承自V

JavaScript基礎Canvas

dci cee mk4 rip gsl http nbu scrip hud udcizp盅夠推椒創炭http://www.docin.com/bmqgd37060fmh32e扔詡忌畝鉤偎http://jz.docin.com/sina_6188986925e5zku1匱鉸

Android動畫基礎補間動畫與逐幀動畫

Android動畫分類主要分三類: Tweened Animation補間動畫 Frame Animation幀動畫 Property Animation屬性動畫 現在我們來介紹一下補間動畫。Tweened Animation補間動畫,是通過配置動畫檔案

Android Studio基礎依賴管理(五)-學習篇

在我們的專案中,或我或少都會用到一起第三方的庫,那麼對它的管理也就成為了專案中的一部分。這裡就介紹下在Android Studio中如何去管理專案中的庫和它們的依賴。 如何新增一個庫 Android Studio中新增一個庫有三種方法 第一種,直接

Android Studio基礎專案目錄結構(四)-學習篇

開始前先說下什麼是Gradle 這是我在網上找到的對Gradle的描述: At the heart of Gradle lies a rich extensible Domain Specific Language (DSL) based on Gro

Android繪圖例項(Bitmmap,Canvas,Pain的使用)&動態的在圖片上新增文字(canvas.drawText)

近些天學習影象處理,今天看見了一段程式碼中有Bitmap時,找了些Bitmap的資料,有查看了與之有關的繪圖類。 BitMap代表一張點陣圖,BitmapDrawable裡封裝的圖片就是一個Bitmap物件,開發者被一個Bitmap物件包裝成BitmapDrawable物

Android 繪圖基礎:Path(繪製三角形、貝塞爾曲線、正餘弦)

學習重點: 理解path的使用 理解貝塞爾曲線的繪製原理 可動正餘弦的繪製 Path的簡單介紹   在 Android 繪圖基礎:Canvas畫布——自定義View(繪製錶盤、矩形、圓形、弧、漸變) 中我們可以看到Canvas的強大功能,其實Canva

Android 繪圖基礎:Bitmap(點陣圖)與Matrix(矩陣)實現圖片5種操作(平移、旋轉、錯切、縮放、對稱)

Android的Matrix利用數學原理實現圖片平移、旋轉等操作詳解   很慶幸自己的線性代數學的還可以,理解Matrix的矩陣變換完全沒有問題。Matrix矩陣實現圖片的平移旋轉等操作涉及到線性代數問題,感興趣它的具體實現的話可以參考一下上面的部落格,非常詳

Android影象處理Canvas

Canvas的相關函式 clip打頭的函式表示對canvas裁剪成指定的形狀 void clipPath(Path path) void clipPath(Path path,Region.op op

08、Android開發基礎QQ登陸介面的實現

Android開發基礎之QQ登陸介面的實現 思路分析 這個QQ登陸介面怎麼去實現呢? 也是非常簡單的一件事情! 我們整體一個相對佈局,然後上面部分使用一個線性佈局!我們要考慮一下方向即可,對吧! 直接看效果圖吧! 學習怎麼做的話,大家就看視訊好了

初學Android,圖形影象使用Canvas,Paint繪圖(二十五

                下面是一個畫各種圖形的例子,具體的畫圖方法不用特別解釋,看API就可以了先定義一個繼承自View的類DrawViewpackage WangLi.Graphics.MyView;import android.content.Context;import android.grap

android 繪圖Path與Paint詳解[轉]

/** * Paint類介紹 * * Paint即畫筆,在繪圖過程中起到了極其重要的作用,畫筆主要儲存了顏色, * 樣式等繪製資訊,指定了如何繪製文字和圖形,畫筆物件有很多設定方法, * 大體上可以分為兩類,一類與圖形繪製相關,一類與文字繪製相關。 * * * 1.圖形繪製 * setARG

Android繪圖Canvas狀態儲存和恢復(7)

1 Canvas 狀態儲存和恢復 前面講canvas概念理解時 已經講解了save和savelayer,saveLayerAlpha函式,這裡進行canvas狀態儲存和恢復的詳細講解。 Canvas 呼叫了translate,scale,rotate,skew,concat or

Android繪圖Canvas變換(6)

1 Canvas 與螢幕 前面講解了Canvas的基本概念,Android繪圖之Canvas概念理解(5) , 對Canvas的概念進行了分析,但是沒有說明和螢幕的關係,Canvas不等於螢幕,螢幕不會動的,我們也無法對螢幕進行(平移,縮放等)操作,只能對Canvas進行操作,所以對

Android繪圖總結(Bitmap,CanvasPaint,圓角)

最近老是和繪圖打交道,經常用到Canvas,bitmap,Paint,但是對它們的理解總是模糊,這裡作下總結,加深對繪圖的理解。 要掌握Android的畫圖,首先就要了解一下,基本用到的圖形介面: 1.Bitmap,可以來自資源/檔案,也可以在程式中建立,實際上的功

Android 2D繪圖(Canvas+paint)詳解

目錄:1.重要類概述2.重要類的常用方法2.簡單View繪製(圓、圓弧、矩形、弧形、圓角矩形、橢圓、文字等)3.setXfermode(Xfermode xfermode)的運用 1.重要類概述在2D繪製中我們常用的類,也是兩個最重要的類就是Canvas(畫布)和Paint

蝸牛—Android基礎button監聽器

自適應 ack cti tool stat action per onclick nts XML文件中有一個textView 和 一個button。 <LinearLayout xmlns:android="http://schemas.android.com/a