What is PorterDuff.Mode
public Xfermode setXfermode(Xfermode xfermode) {
long xfermodeNative = 0;
if (xfermode != null)
xfermodeNative = xfermode.native_instance;
native_setXfermode(mNativePaint, xfermodeNative);
mXfermode = xfermode;
return xfermode;
}复制代码
In android SDK Paint class has a very important method setXfermode (as source), the method for setting the image transition mode, called the transition is an image of the performance parameters of the calculation result of saturation of the image, the color values and the like. In the SDK Xfermode there are three sub-categories: AvoidXfermode, PixelXorXfermode and PorterDuffXfermode, the first two classes was abandoned in the API 16 and is not the subject matter of this article, we will not be described here. PorterDuffXfermode transition class is mainly used for image synthesis mode graphics computing, from its concept in 1984 published "Compositing digital images (digital image synthesis)," the Tomas Porter and Tom Duff, a composite image on the ACM SIGGRAPH Computer Graphics Publications the concept has greatly promoted the development of graphic iconography, PorterDuffXfermode class name comes from a combination of the names that both men PorterDuff. Mode The following is an enumeration type definition in PorterDuff of android SDK.
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;
}
/**
* @hide
*/
public final int nativeInt;
}
复制代码
The above comments for each of the code patterns are described and the alpha channel calculation of the color value mode, to be understood that the specific meaning of each element is calculated for each mode need to figure out the formula:
Sa:全称为Source alpha,表示源图的Alpha通道;
Sc:全称为Source color,表示源图的颜色;
Da:全称为Destination alpha,表示目标图的Alpha通道;
Dc:全称为Destination color,表示目标图的颜色.
复制代码
When the value of Alpha channel 1, the image is completely visible; Alpha channel when the value is 0, the image is completely invisible; Alpha channel when the value between 0 and 1, only a portion of the visible image. Alpha channel is described shape of the image, rather than the transparency.
SCREEN computationally example: [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc], "[......]" was divided into two parts, "" front portion "Sa + Da - Sa * Da "calculated value represents SCREEN mode Alpha channel, and" "portion, the" Sc + Dc - Sc * Dc " calculated color values SCREEN mode, images after the pattern mixing virtue of this vector calculating ARGB value . Alpha knowledge about the image synthesis see Wikipedia Alpha compositing .
1.PorterDuff.Mode.CLEAR
The draw will not be submitted to the canvas.
2.PorterDuff.Mode.SRC
Display top draw pictures
3.PorterDuff.Mode.DST
Show lower draw pictures
4.PorterDuff.Mode.SRC_OVER
Display normal drawing, overlaps the lower drawing.
5.PorterDuff.Mode.DST_OVER
Upper and lower layers are displayed. Home on the lower display.
6.PorterDuff.Mode.SRC_IN
Taking the intersection of two drawing. The upper display.
7.PorterDuff.Mode.DST_IN
Taking the intersection of two drawing. The lower display.
8.PorterDuff.Mode.SRC_OUT
Take the upper part of the draw non-intersection.
9.PorterDuff.Mode.DST_OUT
Drawing the non-intersection portion and the lower layer.
10.PorterDuff.Mode.SRC_ATOP
And the lower layer and the upper layer portion of the non-intersection of the intersection portion
11.PorterDuff.Mode.DST_ATOP
The upper layer portion and the non-intersection of the intersection of the lower portion
12.PorterDuff.Mode.XOR
XOR: removal of part of the intersection of two layers
13.PorterDuff.Mode.DARKEN
The entire area take two layers, the color deepened part of the intersection
14.PorterDuff.Mode.LIGHTEN
All take two layers, part of the color lighting intersection
15.PorterDuff.Mode.MULTIPLY
Take two superimposed layers after color intersection portion
16.PorterDuff.Mode.SCREEN
Take two layers entire region, the intersection portion becomes transparent color
Mode 1
PorterDuff.Mode.DST_IN复制代码
In blend mode when not in use, to draw a rectangle and a circle
public class XfermodeView extends View {
private Paint mPaint;
private int mWidth, mHeight;
public XfermodeView(Context context) {
this(context, null);
}
public XfermodeView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public XfermodeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
//初始化画笔
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = MeasureSpec.getSize(widthMeasureSpec);
mHeight = MeasureSpec.getSize(heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//1.ComposeShader
//2.画笔Paint.setXfermode()
//3.PorterDuffColorFilter
//禁止硬件加速 某些图层模式的APi不支持加速操作
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setBackgroundColor(Color.WHITE);
//离屏绘制 这里将图像合成的处理放到离屏缓存中进行
int layerId = canvas.saveLayer(0,0, getWidth(), getHeight(), mPaint, Canvas.ALL_SAVE_FLAG);
//目标图
canvas.drawBitmap(createRectBitmap(mWidth, mHeight), 0, 0, mPaint);
//在SDK中Xfermode有三个子类:AvoidXfermode, PixelXorXfermode和PorterDuffXfermode,前两个类在API 16被遗弃了,
// 而且不是本文的主题内容,所以这里不作介绍。PorterDuffXfermode
//设置混合模式
//mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
//源图,重叠区域右下角部分
canvas.drawBitmap(createCircleBitmap(mWidth, mHeight), 0, 0, mPaint);
//清除混合模式
mPaint.setXfermode(null);
canvas.restoreToCount(layerId);
}
//画矩形Dst
public Bitmap createRectBitmap(int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint dstPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dstPaint.setColor(0xFF66AAFF);
canvas.drawRect(new Rect(width / 20, height / 3, 2 * width / 3, 19 * height / 20), dstPaint);
return bitmap;
}
//画圆src
public Bitmap createCircleBitmap(int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint scrPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
scrPaint.setColor(0xFFFFCC44);
canvas.drawCircle(width * 2 / 4, height / 3, height / 4, scrPaint);
return bitmap;
}
}复制代码
normal status
复制代码
2 set the blending mode PorterDuff.Mode.SRC
显示上层绘制图片
3 set the blending mode PorterDuff.Mode.The DST
显示下层绘制图片
4. PorterDuff.Mode.SRC_OVER
Display normal drawing, overlaps the lower drawing.
5.PorterDuff.Mode.DST_OVER
Upper and lower layers are displayed. Home on the lower display.
6. 设置混合模式 PorterDuff.Mode.DST_IN
PorterDuff.Mode.DST_IN 取两层绘制交集 显示下层。
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));复制代码
7.PorterDuff.Mode.SRC_IN
Taking the intersection of two drawing. The upper display.
8.PorterDuff.Mode.SRC_OUT
Take the upper part of the draw non-intersection.
9.PorterDuff.Mode.DST_OUT
Drawing the non-intersection portion and the lower layer.
10.PorterDuff.Mode.SRC_ATOP
And the lower layer and the upper layer portion of the non-intersection of the intersection portion
11.PorterDuff.Mode.DST_ATOP
The upper layer portion and the non-intersection of the intersection of the lower portion
12.PorterDuff.Mode.XOR
XOR: removal of part of the intersection of two layers
13.PorterDuff.Mode.DARKEN
The entire area take two layers, the color deepened part of the intersection
14.PorterDuff.Mode.LIGHTEN
All take two layers, part of the color lighting intersection
15.PorterDuff.Mode.MULTIPLY
Take two superimposed layers after color intersection portion
16.PorterDuff.Mode.SCREEN
Take two layers entire region, the intersection portion becomes transparent color
Reproduced in: https: //juejin.im/post/5cf61caff265da1b8e708be1