高級(jí)UI<第十六篇>:Xfermode 詳解

文章參考了各個(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)注釋脱衙,效果如下


圖片.png
  • 這里新建了一個(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;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
清除源圖的所有alpha和顏色值巡验;

(2)混合模式之SRC

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
只繪制源圖的alpha和顏色值

(3)混合模式之DST

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
只繪制目標(biāo)圖

(4)混合模式之SRC_OVER

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_OVER;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:

在目標(biāo)圖像的頂部繪制源圖像际插。

(5)混合模式之DST_OVER

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_OVER;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:

在源圖像的頂部繪制目標(biāo)圖像

(6)混合模式之SRC_IN

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_IN;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
只在源圖像和目標(biāo)圖像相交的地方繪制源圖像

(7)混合模式之DST_IN

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_IN;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
只在源圖像和目標(biāo)圖像相交的地方繪制目標(biāo)圖像

(8)混合模式之SRC_OUT

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_OUT;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
只在源圖像和目標(biāo)圖像不相交的地方繪制源圖像

(9)混合模式之DST_OUT

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_OUT;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
只在源圖像和目標(biāo)圖像不相交的地方繪制目標(biāo)圖像

(10)混合模式之SRC_ATOP

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SRC_ATOP;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
在源圖像和目標(biāo)圖像相交的地方繪制源圖像,在不相交的地方繪制目標(biāo)圖像

(11)混合模式之DST_ATOP

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DST_ATOP;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
在源圖像和目標(biāo)圖像相交的地方繪制目標(biāo)圖像显设,在不相交的地方繪制源圖像

(12)混合模式之XOR

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.XOR;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
在源圖像和目標(biāo)圖像重疊之外的任何地方繪制他們框弛,而在不重疊的地方不繪制任何內(nèi)容

(13)混合模式之MULTIPLY

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.MULTIPLY;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
將每個(gè)位置的兩個(gè)像素相乘,除以255捕捂,然后使用該值創(chuàng)建一個(gè)新的像素進(jìn)行顯示瑟枫。結(jié)果顏色=頂部顏色*底部顏色/255

(14)混合模式之ADD

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.ADD;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:飽和度相加

(15)混合模式之SCREEN

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.SCREEN;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
反轉(zhuǎn)每個(gè)顏色,執(zhí)行相同的操作(將他們相乘并除以255)指攒,然后再次反轉(zhuǎn)慷妙。結(jié)果顏色=255-(((255-頂部顏色)*(255-底部顏色))/255)

(16)混合模式之LIGHTEN

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.LIGHTEN;    //混合模式常量

效果如下

圖片.png

現(xiàn)象:
獲得每個(gè)位置上兩幅圖像中最亮的像素并顯示

(17)混合模式之DARKEN

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.DARKEN;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:
獲得每個(gè)位置上兩幅圖像中最暗的像素并顯示

(18)混合模式之OVERLAY

常量設(shè)置如下

private PorterDuff.Mode xfermodemode = PorterDuff.Mode.OVERLAY ;    //混合模式常量

效果如下


圖片.png

現(xiàn)象:

疊加。

[本章完...]

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末允悦,一起剝皮案震驚了整個(gè)濱河市膝擂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌隙弛,老刑警劉巖猿挚,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異驶鹉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)铣墨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門室埋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伊约,你說我怎么就攤上這事姚淆。” “怎么了屡律?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵腌逢,是天一觀的道長。 經(jīng)常有香客問我超埋,道長搏讶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任霍殴,我火速辦了婚禮媒惕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘来庭。我一直安慰自己妒蔚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肴盏,像睡著了一般科盛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上菜皂,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天贞绵,我揣著相機(jī)與錄音,去河邊找鬼幌墓。 笑死但壮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的常侣。 我是一名探鬼主播蜡饵,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼胳施!你這毒婦竟也來了溯祸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤舞肆,失蹤者是張志新(化名)和其女友劉穎焦辅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椿胯,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筷登,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哩盲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片前方。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖廉油,靈堂內(nèi)的尸體忽然破棺而出惠险,到底是詐尸還是另有隱情,我是刑警寧澤抒线,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布班巩,位于F島的核電站,受9級(jí)特大地震影響嘶炭,放射性物質(zhì)發(fā)生泄漏抱慌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一旱物、第九天 我趴在偏房一處隱蔽的房頂上張望遥缕。 院中可真熱鬧,春花似錦宵呛、人聲如沸单匣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽户秤。三九已至码秉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鸡号,已是汗流浹背转砖。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鲸伴,地道東北人府蔗。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像汞窗,于是被迫代替她去往敵國和親姓赤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容