Paint API - Detailed explanation of Xfermode and PorterDuff (2)


Introduction to this section:

In the previous section, we learned about the two deceased (outdated) sons of Xfermode: AvoidXfermode, PixelXorXfermode, Although it is somewhat useful, it has been eliminated after all. In this section, we will learn about the third son of Xfermode who is still alive: PorterDuffXfermode;

Let’s first pay attention to the official API document: PorterDuffXfermode ! The document contains very little content. We can see its construction method:

1.png

has only one parameter: PorterDuff.Mode mode, and Android provides us with 16 image mixing modes. , it can be simpler It is understood that two layers can be combined into different results and displayed according to different modes! The results of the 16 mixing modes are as follows:

2.png

There are two layers here: the picture drawn first is target picture (DST), and the picture drawn later is Source image (SRC)!

Of course, in the document we found that the available modes are not 16, but 18. Two new modes, ADD and OVERLAY, have been added!

Well, it’s useless to say too much. Code is the most practical. In this section, we write the code to verify these 18 modes! 3.gif

PS: The name PorterDuff is actually a combination of two names: Tomas Proter and Tom Duff, who were the first to The god-level person who first proposed the concept of graphic mixing on SIGGRAPH. If you are interested, please Baidu~


Write an example to verify the above picture:

Okay, let’s write an example to verify the above picture, and compare and analyze the results by modifying different modes!

Code implementation:

Step 1: Let’s first write a tool class to get the screen width and height! ScreenUtil.java

/**
 * Created by Jay on 2015/10/23 0023.
 */
public class ScreenUtil {
    /**
     * 获取屏幕宽高,sdk17后不建议采用
     *
     * @param context
     */
    public static int[] getScreenHW(Context context) {
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = manager.getDefaultDisplay();
        int width = display.getWidth();
        int height = display.getHeight();
        int[] HW = new int[] { width, height };
        return HW;
    }

    /**
     * 获取屏幕宽高,建议采用
     *
     * @param context
     */
    public static int[] getScreenHW2(Context context) {
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(dm);
        int width = dm.widthPixels;
        int height = dm.heightPixels;
        int[] HW = new int[] { width, height };
        return HW;
    }

    /**
     * 获取屏幕的宽度
     *
     * @param context
     * @return
     */
    public static int getScreenW(Context context) {
        return getScreenHW2(context)[0];
    }

    /**
     * 获取屏幕的高度
     *
     * @param context
     * @return
     */
    public static int getScreenH(Context context) {
        return getScreenHW2(context)[1];
    }
}

Step 2: Write our custom View class and experiment here! Calculate their positions, then set the lower layer (fixed writing method), then set the lower brush setXfermode, and then It's just drawn on the canvas. What you don't understand may be the calculation of the drawing position. In fact, it's not the case. How do you decide the position? It will be all right! Then let’s take a look at the results one by one. You only need to modify the value of PD_MODE

to set it to a different mode!

Operation renderings

:

1) PorterDuff.Mode.ADD:

4.png Saturation Overlay

2) PorterDuff.Mode.CLEAR:

5.png The drawn will not Submit it to the canvas, and the result... I don’t know why, normally there is nothing..

3) PorterDuff.Mode.DARKEN:

6.pngTake two layers All areas, the intersection part is darker in color

4) PorterDuff.Mode.DST:

7.pngOnly retains the alpha and color of the target image, so only the target image is drawn

5) PorterDuff.Mode.DST_ATOP:

8.pngThe target image is drawn where the source image and the target image intersect, and the source image is drawn where they do not intersect.

6) PorterDuff.Mode.DST_IN:

9.pngThe target image is drawn where the two intersect, and the drawing effect will be affected by the transparency of the original image

7) PorterDuff.Mode.DST_OUT:

10.pngDraw the target graph at disjoint places

8) PorterDuff.Mode.DST_OVER:

11.pngThe target graph is drawn above

9) PorterDuff.Mode. LIGHTEN:

12.pngTake all areas of the two layers and light up the intersection color

10) PorterDuff.Mode.MULTIPLY:

13.pngTake the two layers The color of the intersection after overlay

11) PorterDuff.Mode.OVERLAY:

14.pngOverlay

12) PorterDuff.Mode.SCREEN:

15.pngTake all areas of the two layers, and the intersection part becomes transparent

13) PorterDuff.Mode.SRC:

16.pngOnly retain the alpha and color of the source image, so draw it Only source image

14) PorterDuff.Mode.SRC_ATOP:

000.pngThe source image is drawn where the source image and the target image intersect, and the target image is drawn where they do not intersect

15) PorterDuff.Mode. SRC_IN:

17.png Draw the source image where the two intersect

16) PorterDuff.Mode.SRC_OUT:

18.png Draw the source image where they do not intersect

17) PorterDuff.Mode.SRC_OVER:

19.pngDraw the source image above

18) PorterDuff.Mode.XOR:

20.pngDraw the source and target images as they are in disjoint places


Download the sample code for this section:

PorterDuffXfermodeDemo.zip


Summary of this section:

Well, in this section I wrote a simple View to verify the different effects of these 18 different PorterDuff.Mode. Hehe, it’s quite time-consuming, but it will definitely seem much clearer to readers, right~ Of course, these are just some preliminary insights!

PorterDuffXfermodePorterDuff.Mode is very important for our custom controls! In this section we have a preliminary understanding. In the next section we will pick a few examples to practice!

If you want to see a more detailed introduction about PorterDuff.Mode, please see: Android Paint's setXfermode PorterDuffXfermode explanation, a good article written by others! Well, that’s it. I’ll have a physical exam tomorrow morning. That’s all I’ll write today~21.jpg