上一篇講了Paint的渲染部分劝评,
UI繪制_Paint的高級(jí)渲染 http://www.reibang.com/p/cce8044d049d
而這篇我們來(lái)學(xué)習(xí)一下圖像混合的mode,通過(guò)使用Xfermode將繪制的圖形的像素和Canvas上對(duì)應(yīng)位置的像素按照一定的規(guī)則進(jìn)行混合倦淀,形成新的像素蒋畜,再更新到Canvas中形成最終的圖形使用的時(shí)候都是通Paint.setXfermode
我們一個(gè)像素的顏色都是由四個(gè)分量組成,即ARGB撞叽,A表示的是我們Alpha值姻成,RGB表示的是顏色,在講解Xfermode的時(shí)候需要了解一下PorterDuff.mode
public class PorterDuff {
public enum Mode {
/** [0, 0] */
CLEAR (0),
/** [Sa, Sc] */
SRC (1),
/** [Da, Dc] */
DST (2),
/** [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */
SRC_OVER (3),
/** [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */
DST_OVER (4),
/** [Sa * Da, Sc * Da] */
SRC_IN (5),
/** [Sa * Da, Sa * Dc] */
DST_IN (6),
/** [Sa * (1 - Da), Sc * (1 - Da)] */
SRC_OUT (7),
/** [Da * (1 - Sa), Dc * (1 - Sa)] */
DST_OUT (8),
/** [Da, Sc * Da + (1 - Sa) * Dc] */
SRC_ATOP (9),
/** [Sa, Sa * Dc + Sc * (1 - Da)] */
DST_ATOP (10),
/** [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] */
XOR (11),
/** [Sa + Da - Sa*Da,
Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */
DARKEN (12),
/** [Sa + Da - Sa*Da,
Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */
LIGHTEN (13),
/** [Sa * Da, Sc * Dc] */
MULTIPLY (14),
/** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */
SCREEN (15),
/** Saturate(S + D) */
ADD (16),
OVERLAY (17);
Mode(int nativeInt) {
this.nativeInt = nativeInt;
}
public final int nativeInt;
}
}
S表示的是原像素愿棋,原像素的值表示[Sa,Sc] Sa表示的就是源像素的Alpha值科展,Sc表示源像素的顏色值
D表示的是目標(biāo)像素,目標(biāo)像素的值表示[Da,Dc] Da表示的就是目標(biāo)像素的Alpha值
效果圖
下面講解一些常用的mode
-
SRC_IN [Sa * Da, Sc * Da]
處理圖片相交區(qū)域時(shí)糠雨,受到目標(biāo)圖片的Alpha值影響才睹,當(dāng)目標(biāo)圖片的透明度為0時(shí),源圖片就不會(huì)顯示
效果如下
核心代碼
int layerId = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
canvas.drawBitmap(dest_img, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
canvas.drawBitmap(src_img, 0, 0, paint);
paint.setXfermode(null);
canvas.restoreToCount(layerId);
- SRC_OUT [Sa * (1 - Da), Sc * (1 - Da)]
和SRC_IN一樣,不同的是當(dāng)目標(biāo)圖片的透明度為不透明時(shí),源圖片就不會(huì)顯示
效果如下
核心
SRC_ATOP [Da, Sc * Da + (1 - Sa) * Dc]
當(dāng)透明度為100%和0%時(shí)琅攘,SRC_IN 和 SRC_ATOP是通用的真椿,當(dāng)透明度不為上述的兩個(gè)值時(shí),SRC_ATOP 比 SRC_IN 源圖像的飽和度會(huì)增加乎澄,變得更亮一些突硝。所以效果上是和SRC_IN一樣的,可以用SRC_IN替換成SRC_ATOPDST_IN [Sa * Da, Sa * Dc]
正好和SRC_IN 相反置济,當(dāng)源圖片的透明度為0的時(shí)候解恰,目標(biāo)圖片完全不顯示
核心代碼
canvas.drawBitmap(src_img, 0, 0, paint);
int layerId = canvas.saveLayer(0, 0, src_img.getWidth(), src_img.getHeight(), null, Canvas.ALL_SAVE_FLAG);
canvas.drawBitmap(dest_img, new Rect(dx, 0, dx + src_img.getWidth(), src_img.getHeight()), new Rect(0, 0, src_img.getWidth(), src_img.getHeight()), paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(src_img, 0, 0, paint);
paint.setXfermode(null);
canvas.restoreToCount(layerId);