一、概述
在顏色合成文章中的最後一個小結當中,我們已經見到了PorterDuff.Mode
這個列舉類,在本次的影象合成中,我們也需要用到這個類,我們先看一下最終呼叫的方法為:
/**
* Set or clear the xfermode object.
* <p />
* Pass null to clear any previous xfermode.
* As a convenience, the parameter passed is also returned.
*
* @param xfermode May be null. The xfermode to be installed in the paint
* @return xfermode
*/
public Xfermode setXfermode(Xfermode xfermode) {
long xfermodeNative = 0;
if (xfermode != null)
xfermodeNative = xfermode.native_instance;
native_setXfermode(mNativePaint, xfermodeNative);
mXfermode = xfermode;
return xfermode;
}
複製程式碼
當一個Paint
被設定了某個Xfermode
時,那麼會根據源圖層、畫筆和Mode
,來決定畫完之後的影象到底是什麼,在使用的時候,我們一般採用PorterDuffXfermode
作為Xfermode
的實現類,它的建構函式的引數就是我們之前說到的PoterDuff.Mode
中的某個型別。
二、混合方式
關於混合的方式,網上有張圖是這麼總結的,其中DST
表示原本有的影象,而SRC
表示即將繪製上去的影象:
http://blog.csdn.net/u010335298/article/details/51983420
他總結了獲得圖中的結果,上面的圖中還有幾個隱含的條件:
- 關閉硬體加速。
- 兩個進行疊加的圖層的大小是相同的。
- 除了有顏色的部分,其它部分都是透明的。
三、示例
下面我們來看一下,DST_ATOP
這種方式
3.1 開啟硬體加速
private void drawPorterDuffXferMode(Canvas canvas) {
Paint paint = new Paint();
//繪製DST影象.
paint.setColor(Color.YELLOW);
canvas.drawCircle(100, 100, 100, paint);
//繪製SRC影象.
paint.setColor(Color.BLUE);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
canvas.drawRect(100, 100, 300, 300, paint);
}
複製程式碼
對應的結果為:
和效果圖完全不符,下面,我們試一下關閉硬體加速:3.2 關閉硬體加速
private void init() {
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
private void drawPorterDuffXferMode(Canvas canvas) {
Paint paint = new Paint();
//繪製DST影象.
paint.setColor(Color.YELLOW);
canvas.drawCircle(100, 100, 100, paint);
//繪製SRC影象.
paint.setColor(Color.BLUE);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
canvas.drawRect(100, 100, 300, 300, paint);
}
複製程式碼
結果為:
還是和理論結果不符合。3.3 使用兩個大小一樣的Bitmap
private Paint mDstPaint;
private Paint mSrcPaint;
private Canvas mDstCanvas;
private Canvas mSrcCanvas;
private Bitmap mSrcBitmap;
private Bitmap mDstBitmap;
private void init() {
setLayerType(LAYER_TYPE_SOFTWARE, null);
mDstPaint = new Paint();
mSrcPaint = new Paint();
mDstPaint.setColor(Color.YELLOW);
mSrcPaint.setColor(Color.BLUE);
mDstBitmap = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
mSrcBitmap = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
mDstCanvas = new Canvas(mDstBitmap);
mSrcCanvas = new Canvas(mSrcBitmap);
}
private void drawPorterDuffXferMode(Canvas canvas) {
//繪製DST影象.
mDstCanvas.drawCircle(100, 100, 100, mDstPaint);
canvas.drawBitmap(mDstBitmap, 0, 0, mDstPaint);
//繪製SRC影象
mSrcCanvas.drawRect(100, 100, 300, 300, mSrcPaint);
mSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
canvas.drawBitmap(mSrcBitmap, 0, 0, mSrcPaint);
}
複製程式碼
來看看這個的結果:
為了得到這個結果,例項化了一堆的物件,並且需要在Bitmap
的大小一樣的時候才可以生效,其實這也不能說是坑,因為根據原始碼來看,計算的計算本來就是取各畫素點的ARGB
進行計算,如果圖層的大小不一樣,那麼計算的結果自然就和上面不同,從圖中來看,它也表明了DST
和SRC
的大小是相同的,並且在除了有顏色之外的部分都是透明的。