天天看點

android5.0:圖檔和顔色

圖檔和顔色

tint屬性

tint屬性一個顔色值,可以對圖檔做顔色渲染,我們可以給view的背景設定tint色值,給ImageView的圖檔設定tint色值,也可以給任意Drawable或者NinePatchDrawable設定tint色值。

在應用的主題中也可以通過設定 

android:tint

 來給主題設定統一的顔色渲染。

tint的渲染模式有總共有16種,xml檔案中可以使用6種,代碼中我們可以設定16種,渲染模式決定了渲染顔色和原圖顔色的取舍和合成規則:

android5.0:圖檔和顔色
  1. PorterDuff.Mode.CLEAR

     所繪制不會送出到畫布上。
  2. PorterDuff.Mode.SRC

     顯示上層繪制圖檔
  3. PorterDuff.Mode.DST

     顯示下層繪制圖檔
  4. PorterDuff.Mode.SRC_OVER

     正常繪制顯示,上下層繪制疊蓋。
  5. PorterDuff.Mode.DST_OVER

     上下層都顯示。下層居上顯示。
  6. PorterDuff.Mode.SRC_IN

     取兩層繪制交集。顯示上層。
  7. PorterDuff.Mode.DST_IN

     取兩層繪制交集。顯示下層。
  8. PorterDuff.Mode.SRC_OUT

     取上層繪制非交集部分。
  9. PorterDuff.Mode.DST_OUT

     取下層繪制非交集部分。
  10. PorterDuff.Mode.SRC_ATOP

     取下層非交集部分與上層交集部分
  11. PorterDuff.Mode.DST_ATOP

     取上層非交集部分與下層交集部分
  12. PorterDuff.Mode.XOR

     取兩層繪制非交集。兩層繪制非交集。
  13. PorterDuff.Mode.DARKEN

     上下層都顯示。變暗
  14. PorterDuff.Mode.LIGHTEN

     上下層都顯示。變亮
  15. PorterDuff.Mode.MULTIPLY

     取兩層繪制交集
  16. PorterDuff.Mode.SCREEN

     上下層都顯示。

通過tint色處理的圖檔會原圖顯示出不一樣的顔色,我們可以通過這種方式利用一張圖檔做出圖檔選擇器的效果,讓控件在按壓狀态下顯示另外一種顔色:

通過給圖檔設定tint色生成另外一種圖檔
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
        android:src="@drawable/ring"
        android:tintMode="multiply"
        android:tint="#5677fc" />
利用新的圖檔生成圖檔選擇器
<selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/tint_bitmap" android:state_pressed="true"/>
        <item android:drawable="@drawable/ring" />
</selector>
           

Palette調色版

Palette調色闆,可以很友善的讓我們從圖檔中提取顔色。并且可以指定提取某種類型的顔色。

  1. Vibrant

     鮮豔的
  2. Vibrant

     dark鮮豔的暗色
  3. Vibrant

     light鮮豔的亮色
  4. Muted

     柔和的
  5. Muted

     dark柔和的暗色
  6. Muted

     light柔和的亮色

對圖檔取色是一個比較消耗性能的操作,其内部會對圖檔的像素值進來周遊以分析對比,是以我們要在異步線程中去完成。

如果操作本來就屬于背景線程,可以使用:
Palette p = Palette.generate(Bitmap bitmap);
如果在主線程中,我們可以使用異步的方式:
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
        public void onGenerated(Palette palette) {  }
});
           

當操作完成後或者異步回調後,我們就可以使用以下方式來擷取對應的色值了,并且可以在沒有擷取到的情況下之指定預設值:

p.getVibrantColor(int defaultColor);
p.getDarkVibrantColor(int defaultColor);
p.getLightVibrantColor(int defaultColor);
p.getMutedColor(int defaultColor);
p.getDarkMutedColor(int defaultColor);
p.getLightMutedColor(int defaultColor);
           

在使用palette之前,bitmap提供擷取指定位置的像素值:

bitmap.getPixel(x,y)
           

但是該方式隻能擷取某一點的像素值,palette是對整個bitmap的所有像素值進行分析,并選出幾個像素占比比較多的像素值,這樣選擇出來的色值更符合圖檔的整體色值。

vector矢量圖

矢量圖也稱為面向對象的圖像或繪圖圖像,是計算機圖形學中用點、直線或者多邊形等基于數學方程的幾何圖元表示圖像。矢量圖形最大的優點是無論放大、縮小或旋轉等不會失真;最大的缺點是難以表現色彩層次豐富的逼真圖像效果。

Android L開始支援矢量圖,我們可以用它來處理一些圖形簡單的icon,友善我們的适配。

Android L中對矢量圖的支援是通過xml檔案建構,通過矢量圖的path描述來生成一個矢量圖,對應的java對象為VectorDrawable。

下面是官方文檔提供的一個矢量圖,利用改檔案,我們可以建立一個随意放大縮小都不會失真的心形

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:height="300dp"
        android:width="300dp"
        android:viewportHeight="40"
        android:viewportWidth="40">
        <path android:fillColor="#ff00ff"
                android:pathData="M20.5,9.5
                        c-1.955,0,-3.83,1.268,-4.5,3
                        c-0.67,-1.732,-2.547,-3,-4.5,-3
                        C8.957,9.5,7,11.432,7,14
                        c0,3.53,3.793,6.257,9,11.5
                        c5.207,-5.242,9,-7.97,9,-11.5
                        C25,11.432,23.043,9.5,20.5,9.5z"/>
</vector>
           

矢量圖的pathData資料就是用來描述矢量圖的數學公式,其含義如下表:

指令類型 使用描述 代表含義 舉例說明
移動指令 M x,y M移動絕對位置 M 100,240
移動指令 m x,y m移動相對于上一個點 m 100,240
繪制指令 L 或 l 從目前點繪制直線到指定點 L 100,100
繪制指令 H 或 h 水準直線 h 100
繪制指令 V 或 v 垂直直線 v 100
繪制指令 C 或 c 三次方程式貝塞爾曲線 C 100,200 200,400 300,200
繪制指令 Q 或 q 二次方程式貝塞爾曲線 Q 100,200 300,200
繪制指令 S 或 s 平滑三次方程式貝塞爾曲線 S 100,200 200,400 300,200
繪制指令 T 或 t 平滑二次方程式貝塞爾曲線 T 100,200 300,200
繪制指令 A 或 a 橢圓 A 5,5 0 0 1 10,10
關閉指令 Z 或 z 将圖形的首、尾點用直線連接配接 Z
填充規則 F0 EvenOdd 填充規則
填充規則 F1 Nonzero 填充規則

通過path指令來進行簡單的圖形還是可行的,但是複雜的圖形我們就需要借助工具來生成了,比如使用 Expression Design,就可以直接粘貼來自其它軟體的矢量圖形,然後選擇導出,導出時做如後選擇:檔案->導出->導出屬性->格式->XAML Silverlight 畫布,即可得到XAML格式的矢量圖形,也就是Path。

繼續閱讀