天天看點

Android學習之Paint圖形圖像處理(一)

是什麼

Paint,顧名思義,就是畫,作動詞畫畫,引申為畫筆,是以paint就相當于我們平常使用的畫筆,而對paint的一些setXXX操作就是日常對畫筆粗細,顔色等的操作,但是程式中的paint可能會比生活中的更強大些。

怎麼樣

API文檔解釋:

The Paint class holds the style and color information about how to draw geometries, text and bitmaps.

從Api定義可知,畫筆持有樣式和顔色資訊,關于怎麼樣的資訊呢,關于如何繪制幾何圖形,文本和位圖的樣式和顔色資訊。

大體分為兩類,圖形繪制和文本繪制。

怎麼用

從構造方法開始看

Android學習之Paint圖形圖像處理(一)

有圖可知,Paint有三個構造方法,

  • 第一個是無參數構造方法,也是預設構造方法,攜帶預設設定,比如預設黑色,無坑鋸齒,不加粗等。
  • 第二個是帶flags參數的構造方法,将光标移到這個構造方法上,會對flags做這樣的解釋
    Android學習之Paint圖形圖像處理(一)

初看以為是flags的枚舉,于是在使用時這樣

Android學習之Paint圖形圖像處理(一)

發現沒有,原來重點在前一句

set the paint's flags

設定paint的flags,當然是用Paint去獲得flags呀~

Android學習之Paint圖形圖像處理(一)

對着api文檔,一一解釋這裡的枚舉類型是什麼作用,也可以直接檢視API文檔

截了一張圖,更直覺

Android學習之Paint圖形圖像處理(一)

分别表示:

- 可抗鋸齒

- 可設定字間距

- 可抖動

- 可設定标記

- 可過濾位圖

- 設定暗示模式為HINTING_OFF,不可暗示

- 設定暗示模式為HINTING_OFF,可暗示

- 設定為線性文本

- 設定為删除線效果文本

- 設定為可亞像素文本

- 設定為下劃線效果文本

當在構造方法中設定了這些值,就不用通過paint對象去設定了,但我個人認為,通過對象去設定更為友善

  • 第三個是設定Paint參數的構造方法,初始化paint的屬性,感覺和第二個構造方法很相似,不知道有啥差別,而且paint都有那麼多setXXX方法了為什麼還要加這兩個個構造方法呢,直接對預設的對象進行設定不行麼?這是我的疑問,可能很無知,但我确實不知道,如果有幸被哪位知道的人看到了,麻煩告訴我一聲,謝謝~

從API開始看

圖形繪制

// 參數1,透明度,參數2:紅,參數3:綠,參數4:藍 均為int 類型,取值範圍0~255,不是小數
setARGB(int a,int r,int g,int b);
//設定透明度,參數同上參數1,取值範圍相同
setAlpha(int a);
//設定顔色,使用顔色值來表示,該顔色值包括透明度和RGB顔色
setColor(int color);
//設定是否坑鋸齒,會消耗大量資源,繪圖速度變慢[這個屬性要實際了解,在後面借用别人的一張圖]
setAntiAlias(boolean b);
//設定是否使用圖像抖動處理,設定為true會使繪制出來的圖像更加平滑飽滿[這個屬性要實際了解,在後面借用别人的一張圖]
setDither(boolean dither);
//設定是否使用圖像抖動處理,如果該項設定為true,則圖像在動畫進行中會濾掉對Bitmap圖像的優化操作,加快顯示速度,但圖檔效果可能會受影響,本設定項依賴于dither和xfermode的設定[這個屬性要實際了解,在後面借用别人的一張圖]

setFilterBitmap(boolean filter);

//設定MaskFilter,可以用不同的MaskFilter實作濾鏡的效果,如濾化,立體等 ,後面在研究
setMaskFilter(MaskFilter maskfilter);

//設定顔色過濾器,可以在繪制顔色時實作不用顔色的變換效果,後面研究
setColorFilter(ColorFilter colorfilter);
//設定畫筆樣式
setStyle(Paint.Style style);

//設定繪制路徑的效果,如點畫線,線畫幾何等
setPathEffect(PathEffect effect)
//設定圖像效果,使用Shader可以繪制出各種漸變效果[後面的文章再詳細複習]
setShader(Shader shader);
//在圖形下面設定陰影層,産生陰影效果,radius為陰影的角度,dx和dy為陰影在x軸和y軸上的距離,color為陰影的顔色
 setShadowLayer(float radius ,float dx,float dy,int color);

//當畫筆樣式為STROKE或FILL_OR_STROKE時,設定筆刷的圖形樣式,如圓形樣式Cap.ROUND,或方形樣式Cap.SQUARE,與setStyle結合使用

setStrokeCap(Paint.Cap cap);

//設定繪制時各圖形的結合方式,如平滑效果等[後面詳細複習]
setSrokeJoin(Paint.Join join);
//設定描邊寬度,與setStroke結合使用
setStrokeWidth(float width);
//設定圖形重疊時的處理方式,如合并,取交集或并集,經常用來制作橡皮的擦除效果,參數設定可參照這篇文章[Xfermode ](http://407827531.iteye.com/blog/1470519)
setXfermode(Xfermode xfermode);
           

文本繪制

//模拟實作粗體文字,如果字型太小會擠成一團,效果不好
setFakeBoldText(boolean fakeBoldText);
//設定設定亞像素文本,該項為true,将有助于文本在LCD螢幕上的顯示效果,該設定與第二個構造方法中SUBPIXE_TEXT_FLAG一樣
setSubpixelText(boolean subpixelText);
//設定繪制文字的對齊方向
setTextAlign(Paint.Align align);
//設定繪制文字x軸的縮放比例,可以實作文字的拉伸的效果
setTextScaleX(float scaleX);
//設定繪制文本的大小
setTextSize(float textSize);
//設定斜體文字,skewX為傾斜弧度
setTextSkewX(float skewX);
//設定Typeface對象,即字型風格,包括粗體,斜體以及襯線體,非襯線體等
//Typeface.DEFAULT:預設字型。Typeface.DEFAULT_BOLD:加粗字型。Typeface.MONOSPACE:monospace字型。Typeface.SANS_SERIF:sans字型。Typeface.SERIF:serif字型。

setTypeface(Typeface typeface);
設定帶有下劃線的文字效果
setUnderlineText(boolean underlineText);
//設定帶有删除線的效果
setStrikeThruText(boolean strikeThruText);
           

着重API

  • setColor(int color)

在xml裡面我們通常使用#加A~F六位或者八位來設定顔色值,帶#号的顔色表示方法

其實就是32位argb的表示方案,然而在setColor裡面我們需要傳入int值,是以需要把#改成0x,比如白色在xml中表示為#ffffff,在java代碼中表示為0xffffff。

  • setARGB(int a,int r.int g,int b)

    和setColor差不多,也是設定顔色值,但這裡是分開設定,同樣的每個參數還可以用十六進制的int值來傳入,比如綠色 #FF00FF00 就可以傳入,setARGB(0xFF,0x00,0xFF,0x00),同理也可以用十進制的來傳入,setARGB(255,0,255,0)

  • setStyle(Paint.Style s)

    設定畫筆的樣式, 樣式取值 有三種:

​Paint.Style.FILL :填充内部

Paint.Style.FILL_AND_STROKE :填充内部和描邊

Paint.Style.STROKE :僅描邊

  • setStrokeWidth(float w)

    設定畫筆描邊寬度

  • setAntAlias(boolean b)

    設定是否坑鋸齒,設定抗鋸齒會增加資源消耗,使繪制時間增長。

    盜用五長老的圖加以了解

    Android學習之Paint圖形圖像處理(一)
  • setStrokeJoin(Paint.Join j)

    設定線段連接配接處​​​的連接配接模式,取值有:

    Join.MITER(結合處為銳角)

    Join.Round(結合處為圓弧)

    Join.BEVEL(結合處為直線)

  • ​setTypeface(Typeface typeface) 字型樣式

    有五種:

    Typeface.DEFAULT:預設字型。

    Typeface.DEFAULT_BOLD:加粗字型。

    Typeface.MONOSPACE:monospace字型。

    Typeface.SANS_SERIF:sans字型。

    Typeface.SERIF:serif字型。

  • setDither(boolean dither);

    設定是否使用圖像抖動處理,會使繪制出來的圖檔顔色更加平滑和飽滿,圖像更加清晰

    這裡我盜用五長老的兩張圖看看效果

    設定為false的情況

    Android學習之Paint圖形圖像處理(一)

設定為true的情況

Android學習之Paint圖形圖像處理(一)

true比false更柔和。

  • setLetterSpacing(float letterSpacing):設定行間距,預設為0
  • setLinearText (boolean linearText)

這個引用五長老的解釋

設定是否打開線性文本辨別,這玩意對大多數人來說都很奇怪不知道這玩意什麼意思。想要明白這東西你要先知道文本在Android中是如何進行存儲和計算的。在Android中文本的繪制需要使用一個bitmap作為單個字元的緩存,既然是緩存必定要使用一定的空間,我們可以通過setLinearText (true)告訴Android我們不需要這樣的文本緩存。
  • setXfermode (Xfermode xfermode)

    參考文章http://407827531.iteye.com/blog/1470519

  • setColorFilter(ColorFilter filter)

    比較複雜,參照文章http://www.cnblogs.com/tianzhijiexian/p/4297104.html

  • reset();畫筆重置,将設定歸0,設為預設值。

Demo

建立項目,建立java類

MyView

繼承View,重寫構造方法和onDraw方法

package com.cd.paintdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Xfermode;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by Sky
 * on 2016/10/28.
 * Describe:
 */

public class MyView extends View {
    Paint mPaint;

    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //指定畫布的背景為白色
        canvas.drawColor(Color.WHITE);
        //建立采用預設設定的畫筆
        mPaint=new Paint();
        //使用坑鋸齒功能
        mPaint.setAntiAlias(true);
        //設定筆觸的寬度
        mPaint.setStrokeWidth();
        //設定填充樣式為描邊
        mPaint.setStyle(Paint.Style.STROKE);
        //繪制藍色的圓形
        mPaint.setColor(Color.BLUE);
        canvas.drawCircle(,,,mPaint);
        //繪制黃色的圓形
        mPaint.setColor(Color.YELLOW);
        canvas.drawCircle(,,,mPaint);
        //繪制黑色的圓形
        mPaint.setColor(Color.BLACK);
        canvas.drawCircle(,,,mPaint);
        //繪制綠色的圓形
        mPaint.setColor(Color.GREEN);
        canvas.drawCircle(,,,mPaint);
        //繪制紅色的圓形
        mPaint.setColor(Color.RED);
        canvas.drawCircle(,,,mPaint);
    }
}
           

删除xml中預設的textview,使用自定義的這個view

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.cd.paintdemo.MainActivity">

    <com.cd.paintdemo.MyView
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>
           

運作結果

Android學習之Paint圖形圖像處理(一)

參考文章:

http://www.jianshu.com/p/7116e1b429c0

http://www.jianshu.com/p/be3785a33582

http://www.jianshu.com/p/f801a4528651

http://www.jianshu.com/p/3edecb48aa68