文章參考了各個(gè)擊破搞明白PorterDuff.Mode這篇文章觅廓,所以本人只演示效果:
案例中涉及到圖層,了解圖層的使用請(qǐng)看高級(jí)UI<第十七篇>:Canvas圖層的概念(saveLayer)
代碼
public class PorterDuffXfermodeView extends View {
private Paint mPaint;
private Xfermode mXfermode;
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.CLEAR; //混合模式常量
private int measureWidth;//父布局寬度
private int measureHeight;//父布局高度
private int OFFSET = 100;//偏移量
public PorterDuffXfermodeView(Context context) {
super(context);
init();
}
public PorterDuffXfermodeView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public PorterDuffXfermodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public PorterDuffXfermodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
/**
* 初始化數(shù)據(jù)
*/
private void init(){
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
//生成混合模式對(duì)象
mXfermode = new PorterDuffXfermode(xfermodemode);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measureWidth = MeasureSpec.getSize(widthMeasureSpec);
measureHeight = MeasureSpec.getSize(heightMeasureSpec);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#cc99ff"));
int saveCount1 = canvas.saveLayer(OFFSET,OFFSET,measureWidth - OFFSET,measureHeight - OFFSET,mPaint, Canvas.ALL_SAVE_FLAG);
mPaint.setColor(Color.YELLOW);
canvas.drawCircle(300, 300, 100, mPaint);
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.dst),null, new RectF(100, 100, 500, 500), mPaint);
mPaint.setXfermode(mXfermode);
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.src), null, new RectF(100, 100, 500, 500), mPaint);
mPaint.setXfermode(null);
canvas.restoreToCount(saveCount1);
}
}
混合模式的代碼已經(jīng)注釋脱衙,效果如下
- 這里新建了一個(gè)圖層帮碰,分別畫了三個(gè)圖形掺喻,假設(shè)分別為A(黃)盯漂、B(綠)、C(紅 )
- 代碼中將紅色圖片設(shè)置了混合模式去件,所以紅色圖片為源圖坡椒,黃色圖片和綠色圖片的并集為目標(biāo)圖
Sa:全稱為Source alpha,表示源圖的Alpha通道尤溜;
Sc:全稱為Source color倔叼,表示源圖的顏色;
Da:全稱為Destination alpha宫莱,表示目標(biāo)圖的Alpha通道丈攒;
Dc:全稱為Destination color,表示目標(biāo)圖的顏色.
(1)混合模式之CLEAR
將注釋打開, 常量設(shè)置如下:
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.CLEAR; //混合模式常量
效果如下
現(xiàn)象:
清除源圖的所有alpha和顏色值巡验;
(2)混合模式之SRC
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC; //混合模式常量
效果如下
現(xiàn)象:
只繪制源圖的alpha和顏色值
(3)混合模式之DST
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST; //混合模式常量
效果如下
現(xiàn)象:
只繪制目標(biāo)圖
(4)混合模式之SRC_OVER
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_OVER; //混合模式常量
效果如下
現(xiàn)象:
在目標(biāo)圖像的頂部繪制源圖像际插。
(5)混合模式之DST_OVER
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_OVER; //混合模式常量
效果如下
現(xiàn)象:
在源圖像的頂部繪制目標(biāo)圖像
(6)混合模式之SRC_IN
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_IN; //混合模式常量
效果如下
現(xiàn)象:
只在源圖像和目標(biāo)圖像相交的地方繪制源圖像
(7)混合模式之DST_IN
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_IN; //混合模式常量
效果如下
現(xiàn)象:
只在源圖像和目標(biāo)圖像相交的地方繪制目標(biāo)圖像
(8)混合模式之SRC_OUT
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_OUT; //混合模式常量
效果如下
現(xiàn)象:
只在源圖像和目標(biāo)圖像不相交的地方繪制源圖像
(9)混合模式之DST_OUT
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_OUT; //混合模式常量
效果如下
現(xiàn)象:
只在源圖像和目標(biāo)圖像不相交的地方繪制目標(biāo)圖像
(10)混合模式之SRC_ATOP
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_ATOP; //混合模式常量
效果如下
現(xiàn)象:
在源圖像和目標(biāo)圖像相交的地方繪制源圖像,在不相交的地方繪制目標(biāo)圖像
(11)混合模式之DST_ATOP
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_ATOP; //混合模式常量
效果如下
現(xiàn)象:
在源圖像和目標(biāo)圖像相交的地方繪制目標(biāo)圖像显设,在不相交的地方繪制源圖像
(12)混合模式之XOR
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.XOR; //混合模式常量
效果如下
現(xiàn)象:
在源圖像和目標(biāo)圖像重疊之外的任何地方繪制他們框弛,而在不重疊的地方不繪制任何內(nèi)容
(13)混合模式之MULTIPLY
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.MULTIPLY; //混合模式常量
效果如下
現(xiàn)象:
將每個(gè)位置的兩個(gè)像素相乘,除以255捕捂,然后使用該值創(chuàng)建一個(gè)新的像素進(jìn)行顯示瑟枫。結(jié)果顏色=頂部顏色*底部顏色/255
(14)混合模式之ADD
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.ADD; //混合模式常量
效果如下
現(xiàn)象:飽和度相加
(15)混合模式之SCREEN
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SCREEN; //混合模式常量
效果如下
現(xiàn)象:
反轉(zhuǎn)每個(gè)顏色,執(zhí)行相同的操作(將他們相乘并除以255)指攒,然后再次反轉(zhuǎn)慷妙。結(jié)果顏色=255-(((255-頂部顏色)*(255-底部顏色))/255)
(16)混合模式之LIGHTEN
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.LIGHTEN; //混合模式常量
效果如下
現(xiàn)象:
獲得每個(gè)位置上兩幅圖像中最亮的像素并顯示
(17)混合模式之DARKEN
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DARKEN; //混合模式常量
效果如下
現(xiàn)象:
獲得每個(gè)位置上兩幅圖像中最暗的像素并顯示
(18)混合模式之OVERLAY
常量設(shè)置如下
private PorterDuff.Mode xfermodemode = PorterDuff.Mode.OVERLAY ; //混合模式常量
效果如下
現(xiàn)象:
疊加。
[本章完...]