Xfermode layer blend

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

Guess you like

Origin blog.csdn.net/weixin_34148508/article/details/91455684