8.3.5 Paint API - A Detailed Explanation of Xfermode and PorterDuff (Part II)
Category Android Basic Tutorial
Introduction to This Section:
>
In the previous section, we studied the two deceased (obsolete) sons of Xfermode: AvoidXfermode, PixelXorXfermode, although they have some use, they are ultimately phased out. In this section, let's learn about Xfermode's three surviving sons: PorterDuffXfermode;
First, let's offer the official API documentation: PorterDuffXfermode! The document is concise, and we can see its constructor:
The parameter has only one: PorterDuff.Mode mode, and Android provides us with 16 image blending modes. It can be simply understood that two layers can be combined into different results according to different modes! The results of the 16 blending modes are shown in the following figure:
Here are two layers: the first drawn picture is the destination image (DST), and the picture drawn later is the source image (SRC)!
Of course, in the document, we find that the available modes are not 16, but 18, with the addition of ADD and OVERLAY two modes!
Well, it's no use talking too much, the code is the most practical, let's write the code in this section to verify these 18 modes!
PS: The naming of PorterDuff is actually a combination of two names: Tomas Proter and Tom Duff, they are the great figures who first proposed the concept of graphic blending at SIGGRAPH, those who are interested can search Baidu by themselves~
Write an Example to Verify the Above Picture:
>
Okay, let's write an example to verify the picture above, by modifying different modes, to compare and analyze the results!
Code Implementation :
Step 1: Let's first write a utility class to get the screen width and height! ScreenUtil.java:
/**
* Created by Jay on 2015/10/23 0023.
*/
public class ScreenUtil {
/**
* Get the screen width and height, not recommended after 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;
}
/**
* Get the screen width and height, recommended
*
* @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;
}
/**
* Get the screen width
*
* @param context
* @return
*/
public static int getScreenW(Context context) {
return getScreenHW2(context)[0];
}
/**
* Get the screen height
*
* @param context
* @return
*/
public static int getScreenH(Context context) {
return getScreenHW2(context)[1];
}
}
Step 2: Write our custom View class, and do experiments here! XfermodeView.java:
``` /**
- Created by Jay on 2015/10/23 0023. */ public class XfermodeView extends View {
private PorterDuffXfermode pdXfermode; // Define PorterDuffXfermode variable
// Define MODE constants, you can directly change here to test
private static PorterDuff.Mode PD_MODE = PorterDuff.Mode.ADD;
private int screenW, screenH; // Screen width and height
private int width = 200; // The width and height of the drawing picture
private int height = 200;
private Bitmap srcBitmap, dstBitmap; // The Bitmap of the upper SRC and the lower Dst
public XfermodeView(Context context) {
this(context, null);
}
public XfermodeView(Context context, AttributeSet attrs) {
super(context, attrs);
screenW = ScreenUtil.getScreenW(context);
screenH
The code may seem complex, but it's not really. It's just about getting the screen width and height, then drawing a rectangle and a circle, calculating their positions, setting up the layers (fixed syntax), and then setting the paint transfer mode with setXfermode, and finally drawing onto the canvas. What you might not understand is the calculation of the drawing positions, but in fact, you can set the positions however you like! So let's take a look at the results one by one. You just need to change the value of PD_MODE to different modes!
Running Effect Images :
1) PorterDuff.Mode.ADD:
2) PorterDuff.Mode.CLEAR:
3) PorterDuff.Mode.DARKEN:
4) PorterDuff.Mode.DST:
5) PorterDuff.Mode.DST_ATOP:
6) PorterDuff.Mode.DST_IN:
7) PorterDuff.Mode.DST_OUT:
8) PorterDuff.Mode.DST_OVER:
9) PorterDuff.Mode.LIGHTEN:
10) PorterDuff.Mode.MULTIPLY:
11) PorterDuff.Mode.OVERLAY:
12) PorterDuff.Mode.SCREEN:
13) PorterDuff.Mode.SRC:
14) PorterDuff.Mode.SRC_ATOP:
15) PorterDuff.Mode.SRC_IN:
16) PorterDuff.Mode.SRC_OUT:
17) PorterDuff.Mode.SRC_OVER:
18) PorterDuff.Mode.XOR:
Download the Example Code for This Section:
Summary of This Section:
>
Well, this section just wrote a simple View to verify the different effects under these 18 different PorterDuff.Mode modes. Hehe, it's quite time-consuming, but it definitely looks clearer for the readers, right? Of course, these are just some preliminary insights!
The PorterDuff.Mode of PorterDuffXfermode is very important for our custom controls! We have a preliminary understanding of it in this section, and in the next section, we will choose a few examples to practice!
If you want to see a more detailed introduction to PorterDuff.Mode, you can refer to: Android Paint setXfermode PorterDuffXfermode Explanation, a well-written article by someone else!
Well, that's it for now. I have a physical examination tomorrow morning, so I'll write this much for today.
-1.0.1 The Latest Android Basic Tutorial Catalogue for 2015
-1.1 Background and System Architecture Analysis
-1.2 Development Environment Setup
-1.2.1 Developing Android APPs with Eclipse + ADT + SDK
-1.2.2 Developing Android APPs with Android Studio
-1.3 Solving SDK Update Issues
-1.4 Genymotion Emulator Installation
-1.5.1 Git Tutorial on Basic Operations of Local Repositories
-1.5.2 Git and Setting Up a Remote Repository with GitHub
-1.6 How to Play with 9-Patch Images
-1.7 Interface Prototype Design
-1.8 Project Related Analysis (Various Files, Resource Access)
-1.9 Android Program Signing and Packaging
-1.11 Decompiling APK to Retrieve Code & Resources
-2.1 The Concept of View and ViewGroup
-2.2.1 LinearLayout (Linear Layout)
-2.2.2 RelativeLayout (Relative Layout)
-[
3.6 Responding to System Setting Events (Configuration Class)
4.4.2 ContentProvider: A Further Exploration - Document Provider
5.2.1 Fragment Example: Implementing a Bottom Navigation Bar (Method 1)
5.2.2 Fragment Example: Implementing a Bottom Navigation Bar (Method 2)
5.2.3 Fragment Example: Implementing a Bottom Navigation Bar (Method 3)
5.2.4 Fragment Example: Bottom Navigation Bar + ViewPager for Page Switching
5.2.5 Fragment Example: A Simple Implementation of a News (Shopping) App List Fragment
6.2 Data Storage and Access: SharedPreferences for Saving User Preferences
6.3.1 Data Storage and Access: An Introduction to SQLite Database
6.3.2 Data Storage and Access: Another Look at SQLite Database
7.1.1 Learning Android Network Programming and HTTP Protocol
7.1.2 Learning About Android HTTP Request and Response Headers
[7.6.3 Socket Communication Based on TCP Protocol (
11.0 "2015 Latest Android Basic Tutorial" Concludes with Fireworks~
12.2 DrySister Girl Viewing App (First Edition) -- 2. Parsing Backend Data
12.4 DrySister Girl Viewing App (First Edition) -- 4. Adding Data Caching (Integrating SQLite)