Paint API之- Xfermode與PorterDuff詳解(一)
本節引言:
不知道標題這兩個玩意你熟不熟悉啦,如果自己實現過圓角或圓形圖片,相信對這兩個名詞 並不模式,一時半夥沒想起來?沒關係,下面這個圖你可看過?
PS:網路上都說在:\samples\android-XX\legacy\ApiDemos\src\com\example\android\apis\graphics 下能找到這個圖片- -,然而並沒有,不知道是不是因為我的sample是android-22的,只在這裡找到一個Xfermodes.java的Java檔!這裡直接貼下網路上找到的~
嗯,說回來,這圖相信大部分朋友都看過吧,沒看過也沒關係,本節我們帶大家來一點點的學習 這個東西~,看回我們前面的Android基礎入門教程——8.3.1 三個繪圖工具類別詳解
setXfermode(Xfermode xfermode):設定圖形重疊時的處理方式,如合併,取交集或併集, 常用來製作橡皮擦的擦除效果!
我們來到官方文件:Xfermode,我們發現他有三個兒子:
本節我們來學習他的前兩個兒子~
大兒子:AvoidXfermode
嗯,和前面學的MaskFilter的兩個子類別一樣,不支援硬體加速,所以如果是API 14以上的版本, 需要關閉硬體加速才會有效果!怎麼關自己看上一節哈~
我們來看看他提供給我們的構造方法!官方API文件:AvoidXfermode
參數有三個,依序是:
opColor:一個十六進位的帶透明度的顏色值,例如0x00C4C4;
tolerance:容差值,如果你學過PS可能用過魔棒工具,就是設定選取顏色值的範圍,例如 容差為0,你選的是純黑的小點,當容差調至40的時候,範圍已經擴大到大塊黑色這樣!如果 還不是很明白,等下我們寫寫程式就知道了!
mode:AvoidXfermode模式,有兩種:TARGET與AVOID
模式1 :AvoidXfermode.Mode.TARGET
該模式會判斷畫布上是否有與我們設定顏色值不一樣的顏色,如果有的話,會把這些區域 染上一層畫筆定義的顏色,其他地方不染色!下面我們寫程式碼示範下,順便讓大家感覺下 這個容差值!
使用程式碼範例:
#運行效果圖:
嗯,先上下原圖,素材來自 gank.io:
接下來我們隨便把牆上某個地方的顏色用顏色取色器取下,然後寫一個簡單的View!
PS:需要在AndroidManifest.xml中的appliction節點添加關閉硬體加速:android:hardwareAccelerated="false"
/** * Created by Jay on 2015/10/22 0022. */ public class AvoidXfermodeView1 extends View { private Paint mPaint; private Bitmap mBitmap; private AvoidXfermode avoidXfermode; public AvoidXfermodeView1(Context context) { super(context); init(); } public AvoidXfermodeView1(Context context, AttributeSet attrs) { super(context, attrs); init(); } public AvoidXfermodeView1(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿 avoidXfermode = new AvoidXfermode(0XFFCCD1D4, 0, AvoidXfermode.Mode.TARGET); mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.iv_meizi); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBitmap, 50, 50, mPaint); mPaint.setARGB(255, 222, 83, 71); mPaint.setXfermode(avoidXfermode); canvas.drawRect(50, 50, 690, 1010, mPaint); } }
#:
看到牆上那堆姑姑紅了沒,效果槓槓的,這裡我們的容差值並沒有發揮作用,我們改一改,把 妹子的白衣服變成姨媽紅!
我們把上面構造AvoidXfermode的內容改成:
avoidXfermode = new AvoidXfermode(0XFFD9E5F3, 25, AvoidXfermode.Mode.TARGET);
然後,妹子身上的白衣服就變成姨媽紅了...,滿滿的罪惡感.. .
模式2:AvoidXfermode.Mode.AVOID
和上面的TARGET模式相反,上面是顏色一樣才改變顏色,這裡是顏色不一樣反而改變顏色, 而容差值同樣帶來相反的結果,容差值為0時,只有當圖片中的像素顏色值與設定的顏色值完全不一樣 的時候才會被染色,而當容差值達到最大值255的時候,稍微有一點顏色不一樣就會被染色! 我們只需簡單的修改上面的例子就可以了,同一是修改下構造AvoidXfermode的內容! 我們改成下面這句話:
avoidXfermode = new AvoidXfermode(0XFFD9E5F3,230, AvoidXfermode.Mode.AVOID);
運行效果圖:
二兒子:PixelXorXfermode
這個則是另一個影像混排模式,比起大兒子簡單,他的建構方法如下:
官方API文件:PixelXorXfermode
#參數解析:
就一個16進位帶透明值得顏色值,至於這個值的作用,是有一個演算法的: PixelXorXfermode內部是依照" opColor ^ src ^ dst "這個異或演算法運算的, 得到一個不透明的(alpha = 255)的色彩值,設定到圖像中!好吧,這是網路搜尋的 具體我也不知道,寫範例試試看效果唄~
程式碼範例:
執行效果圖:
實作程式碼:
/** * Created by Jay on 2015/10/22 0022. */ public class PixelXorXfermodeView1 extends View{ private Paint mPaint; private Bitmap mBitmap; private PixelXorXfermode pixelxorXfermode; public PixelXorXfermodeView1(Context context) { super(context); init(); } public PixelXorXfermodeView1(Context context, AttributeSet attrs) { super(context, attrs); init(); } public PixelXorXfermodeView1(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿 pixelxorXfermode = new PixelXorXfermode(0XFFD9E5F3); mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.iv_meizi); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBitmap, 50, 50, mPaint); mPaint.setARGB(255, 222, 83, 71); mPaint.setXfermode(pixelxorXfermode); canvas.drawRect(50, 50, 690, 1010, mPaint); } }
#本節範例程式碼下載:
本節小結:
好吧,滿滿的罪惡感,很漂亮的一個妹子,結果給我寫demo寫成了這個樣子,別怪我,嗯,對了,忘記說,Xfermode的大兒子和二兒子已經過世(過期),在API 16後的版本,就 過期了,也就說本節並沒什麼卵用...
也不能這樣說,Apache在4.4後的版本都給閹割了,但是還是有人用著HttpClient,或者 由這個庫寫的HTTP請求框架哈~當然,這種人基本上很少很少!不過學多點總沒壞處,對吧, 下節的三兒子PorterDuffXfermode就沒過時啦,也很重要,嗯,放心,不會又會毀照片! 嗯,就說這麼多,謝謝~