Android Image Processing-Xfermode of painting, androidxfermode

Source: Internet
Author: User

Android Image Processing-Xfermode of painting, androidxfermode

Reprinted please indicate the source:Http://blog.csdn.net/allen315410/article/details/45077165

In my previous blog, I summarized several subclasses and usage RELATED TO THE ColorFilter of painting. The most common ColorMatrixColorFilter is worth learning, by defining a 4*5 matrix of the color value, you can set various color effects of the Paint. In addition, there is also porterducolorfilter, which is not used in many cases, but the concepts used in porterducolorfilter are particularly important. We should take a good look at it. PorterDuff is a constant graphical hybrid model invented by foreigners, in addition, the Android API provides 18 different mixed mode algorithms for us. We usually need to understand the meanings and usage of these models during development, it is flexible to use these modes to freely mix the image effects we need.


Xfermode

To be honest, I don't know how to translate Xfermode. I am used to calling it a mixed image mode. Whatever it is, it doesn't prevent us from using it. For instructions on Xfermode, you can find this description in the Google document: Xfermode is the base class for customizing the "Transfer Mode" in the drawing channel. Static function creation can call or return any predefined subclass instance specified as the mode enumeration. When Xfermode is assigned to the Paint, the painting object and the Paint have the added xfermode. It is easier to read. The source code of Xfermode is as follows:

public class Xfermode {    protected void finalize() throws Throwable {        try {            finalizer(native_instance);        } finally {            super.finalize();        }    }    private static native void finalizer(long native_instance);    long native_instance;}
Look, Xfermode is just a bit of code. experience tells us that there must be a subclass under it, wipe it, and change it to yuanfang ~~~

Check the document and find that Xfermode does have AvoidXfermode, PixelXorXfermode, and porterduxfermode. Next we will continue to learn the usage of the three sub-classes.


AvoidXfermode tells you an unfortunate message before reading this subclass. AvoidXfermode does not support hardware acceleration and is not applicable on machines higher than API16. If you want to test this subclass, 1, the hardware acceleration module of the mobile phone can be disabled; 2. In AndroidManifest. set hardware acceleration to false on the Application node in xml.

android:hardwareAccelerated="false"
Under Android Studio, click to view the AvoidXfermode constructor:

public AvoidXfermode(int opColor, int tolerance, Mode mode)
The construction method of AvoidXfermode is also very simple, and a total of three parameters are received: the first parameter opColor is a hexadecimal color value with a transparency channel, such as 0X12345678. The second tolerance parameter indicates the tolerance value. What is the tolerance value? It can be understood as a concept that represents "precision" and "fuzzy". The following will explain it. The third parameter is the AvoidXfermode Mode. AvoidXfermode has two modes: AvoidXfermode. Mode. TARGET and AvoidXfermode. Mode. AVOID.


AvoidXfermode. mode. in this mode, Android will determine whether the color on the canvas is different from that of opColor. For example, if opColor is red, in the TARGET mode, we will determine whether there is any red area on our canvas. If so, we will "Dye" the area to a color defined by our paint brush, otherwise, the color will not be "dyed", while the tolerance value indicates the difference between the pixels on the canvas and the defined red color, for example, the current canvas has a pixel color value (200, 20, 13), while our red value is (255, 0, 0). When tolerance's tolerance value is 255, even if the value (200, 20, 13) is not the same as the value of red, it will be "colored". The larger the value of tolerance, the wider the color range. Otherwise, the greater the color range, the greater the color range, let's look at the specific implementation and effects without saying anything:

Public class CustomView3 extends View {private Paint mPaint; private Bitmap mBitmap; private Context mContext; private int x, y, w, h; private AvoidXfermode avoidXfermode; public CustomView3 (Context context) {this (context, null);} public CustomView3 (Context context, AttributeSet attrs) {super (context, attrs); mContext = context; initRes (); initPaint ();} private void initRes () {// load bitmap mBitmap = BitmapFactory. decodeResource (mContext. getResources (), R. mipmap. image); // obtain the starting layout of the bitmap display x = ScreenUtil. getScreenW (mContext)/2-mBitmap. getWidth ()/2; y = ScreenUtil. getScreenH (mContext)/2-mBitmap. getHeight ()/2; w = ScreenUtil. getScreenW (mContext)/2 + mBitmap. getWidth ()/2; h = ScreenUtil. getScreenH (mContext)/2 + mBitmap. getHeight ()/2;} private void initPaint () {mPaint = new Paint (Paint. ANTI_ALIAS_FLAG); avoidXfermode = new AvoidXfermode (0 XFFFFFFFF, 0, AvoidXfermode. mode. TARGET) ;}@ Override protected void onDraw (Canvas canvas) {canvas. drawBitmap (mBitmap, x, y, mPaint); mPaint. setARGB (255,211, 53,243); mPaint. setXfermode (avoidXfermode); canvas. drawRect (x, y, w, h, mPaint );}}
Run the following command to check the effect. First, make sure that the simulator enabled is under API16, or disable "Hardware acceleration" under the Application node ":

AvoidXfermode (0 XFFFFFFFF, 0, AvoidXfermode. Mode. TARGET ):

As you can see, when our mode is set to TARGET with a tolerance value of 0, only the image color value 0XFFFFFFFF in the image will be colored, and other places will not change.

Next, modify the tolerance value to 255:


AvoidXfermode (0 XFFFFFFFF, 255, AvoidXfermode. Mode. TARGET)

When the tolerance value is 255, it will be colored as long as it is a little close to 0XFFFFFFFF.


AvoidXfermode. mode. AVOID is the opposite of TARGET. TARGET is whether the color we specify is the same as that of the canvas. AVOID is whether the color we specify is different from that of the canvas. Others are similar to TARGET.
AvoidXfermode (0 XFFFFFFFF, 0, AvoidXfermode. Mode. AVOID ):

When the mode is AVOID and the tolerance value is 0, the color of the pixel is stained only when the pixel color value in the image is completely different from 0XFFFFFFFF.
AvoidXfermode (0 XFFFFFFFF, 255, AvoidXfermode. Mode. AVOID ):


When the tolerance value is 255, as long as it is slightly different from 0XFFFFFFFF, it will be stained.
So what is the use of this stuff? For example, this method can be used when we only want to draw something in the white area or replace the white area with another image!


PixelXorXfermode

PixelXorXfermode is another image Mixing Mode in Xfermode, which is very simple. Unfortunately, it is outdated in API16. Let's take a look at the constructor of PixelXorXfermode:

public PixelXorXfermode(int opColor) 
The construction method is very simple. You only need to pass a 16-in-band transparent channel color value. What is the purpose of this parameter? In the Google document, I found an algorithm like this: in fact, PixelXorXfermode performs operations based on the exclusive or algorithm "opColor ^ src ^ dst, get an opaque (alpha = 255) color value and set it to the image. Next we will write a PixelXorXfermode Demo for the image Demo we use above:

Public class CustomView3 extends View {private Paint mPaint; private Bitmap mBitmap; private Context mContext; private int x, y, w, h; private PixelXorXfermode pixelXorXfermode; public CustomView3 (Context context) {this (context, null);} public CustomView3 (Context context, AttributeSet attrs) {super (context, attrs); mContext = context; initRes (); initPaint ();} private void initRes () {// load bitmap mBitmap = BitmapFactory. decodeResource (mContext. getResources (), R. mipmap. image); // obtain the starting layout of the bitmap display x = ScreenUtil. getScreenW (mContext)/2-mBitmap. getWidth ()/2; y = ScreenUtil. getScreenH (mContext)/2-mBitmap. getHeight ()/2; w = ScreenUtil. getScreenW (mContext)/2 + mBitmap. getWidth ()/2; h = ScreenUtil. getScreenH (mContext)/2 + mBitmap. getHeight ()/2;} private void initPaint () {mPaint = new Paint (Paint. ANTI_ALIAS_FLAG); pixelXorXfermode = new PixelXorXfermode (0XFFFF0000);} @ Override protected void onDraw (Canvas canvas) {// draw Bitmap and src Canvas first. drawBitmap (mBitmap, x, y, mPaint); // set a solid color test mPaint. setARGB (255,211, 53,243); // sets Xfermode mPaint. setXfermode (pixelXorXfermode); // mix a solid rectangle (dst) canvas on bitmap. drawRect (x, y, w, h, mPaint );}}
The following figure shows the image after mixing:

In PixelXorXfermode, src has been taken out at the underlying layer. Each dst pixel and opColor perform the opColor ^ src ^ dst operation. The result output is as shown in! Well, I only learned so much, because it is out of date. Similarly, the AvoidXfermode above is also out of date. Just get to know. The following is the third subclass of Xfermode, which is also the only learning method that is not outdated and very important.

Porterduxfermode is also a subclass of Xfermode. Let's take a look at its construction method:
public PorterDuffXfermode(PorterDuff.Mode mode)
The construction method of porterduxfermode is very simple. A PorterDuff must be passed in the construction method. mode parameter, about PorterDuff. mode, which we have learned in the previous blog. In fact, it is the same as the mixed sorting Mode of the ColorFilter subclass porterducolorfilter. The Android system provides a total of 18 mixed sorting modes. In the simulator's ApiDemos/Graphics/XferModes, this figure shows the effects of various mixed sorting modes. Src indicates the source image, Dst indicates the target image, and the two images are displayed as shown in. PorterDuff. mode also provides 18 mixed-Mode algorithms, with two more modes: ADD and OVERLAY. Sa is called Source alpha, which indicates the Alpha channel of the Source image; SC is called Source color to indicate the color of the Source image; Da is called Destination alpha to indicate the Alpha channel of the target image; Dc is called Destination color to indicate the color of the target image, [...,...] the first half calculates the Alpha channel value of the result image, and the second half calculates the color value of the result image. After the image is mixed, the two values are used to re-calculate the ARGB value. I am sorry for the specific algorithm. I don't know, but it doesn't matter, having no knowledge of computing algorithms does not affect the writing of programs by our programmers. We only need to compare the image provided in the above apiDemo to deduce the result of the mixed row. The following will compare the ApiDemos/Graphics/XferModes program to test the effect of each module, the test procedure is as follows:
Public class XfermodeView extends View {// constants in PorterDuff mode can be changed here to test private static final PorterDuff. mode MODE = PorterDuff. mode. CLEAR; private porterduxfermode; private int screenW, screenH; // screen width and height private Bitmap srcBitmap, dstBitmap; // source and target MAP width and height private int width = 120; private int height = 120; public XfermodeView (Context context) {this (context, null);} public XfermodeView (Context context, AttributeSet attrs) {super (context, attrs ); screenW = ScreenUtil. getScreenW (Activity) context); screenH = ScreenUtil. getScreenH (Activity) context); // create a porterduxfermode object porterduxfermode = new porterduxfermode (MODE); // create the source image and target image srcBitmap = makeSrc (width, height ); dstBitmap = makeDst (width, height);} // create a circular bitmap as the dst map private Bitmap makeDst (int w, int h) {Bitmap bm = Bitmap. createBitmap (w, h, Bitmap. config. ARGB_8888); Canvas c = new Canvas (bm); Paint p = new Paint (Paint. ANTI_ALIAS_FLAG); p. setColor (0xFFFFCC44); c. drawOval (new RectF (0, 0, w * 3/4, h * 3/4), p); return bm ;}// create a bitmap rectangle, as src graph private Bitmap makeSrc (int w, int h) {Bitmap bm = Bitmap. createBitmap (w, h, Bitmap. config. ARGB_8888); Canvas c = new Canvas (bm); Paint p = new Paint (Paint. ANTI_ALIAS_FLAG); p. setColor (0xFF66AAFF); c. drawRect (w/3, h/3, w * 19/20, h * 19/20, p); return bm ;}@ Override protected void onDraw (Canvas canvas) {Paint paint = new Paint (); paint. setFilterBitmap (false); paint. setStyle (Paint. style. FILL); // draw the "src" Blue rectangular source image canvas. drawBitmap (srcBitmap, screenW/8-width/4, screenH/12-height/4, paint); // draw a "dst" Yellow circular source image canvas. drawBitmap (dstBitmap, screenW/2, screenH/12, paint); // create a layer to demonstrate the effect of image mixing on the layer int SC = canvas. saveLayer (0, 0, screenW, screenH, null, Canvas. MATRIX_SAVE_FLAG | Canvas. CLIP_SAVE_FLAG | Canvas. HAS_ALPHA_LAYER_SAVE_FLAG | Canvas. FULL_COLOR_LAYER_SAVE_FLAG | Canvas. CLIP_TO_LAYER_SAVE_FLAG); // draw the "dst" yellow circle canvas first. drawBitmap (dstBitmap, screenW/4, screenH/3, paint); // set the Xfermode Paint of paint. setXfermode (porterduduxfermode); canvas. drawBitmap (srcBitmap, screenW/4, screenH/3, paint); paint. setXfermode (null); // restore the canvas. restoreToCount (SC );}}
To facilitate observation, set the background color of Activity_main.xml to black.

1. PorterDuff. Mode. CLEAR. Description: The Source image is not submitted to the canvas.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.CLEAR;


2. PorterDuff. Mode. SRC. English description: only the source image is displayed.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.SRC;



3. PorterDuff. Mode. DST. Description: only the target image is displayed.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.DST;


4. PorterDuff. Mode. SRC_OVER. Description: The Source image is displayed on top of the source image.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.SRC_OVER;



5. PorterDuff. Mode. DST_OVER. Description: both the upper and lower layers are displayed. The target image is displayed on top.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.DST_OVER;



6. PorterDuff. Mode. SRC_IN. Description: source image in the intersection of two layers.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.SRC_IN;



7. PorterDuff. Mode. DST_IN. Description: draws the target image from the intersection of two layers.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.DST_IN;



8. PorterDuff. Mode. SRC_OUT. Description: draws the source image only when the source image and the target image do not overlap.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.SRC_OUT;



9. PorterDuff. Mode. DST_OUT. Description: draws the target image only when the source image and the target image do not overlap.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.DST_OUT;



10. PorterDuff. Mode. SRC_ATOP. Description: draws the source image at the intersection of the source image and the target image at the intersection.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.SRC_ATOP;



11. PorterDuff. Mode. DST_ATOP. Description: Draw the target image at the intersection of the source image and the target image at the intersection.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.DST_ATOP;



12. PorterDuff. Mode. XOR. Chinese description: exclusive or: remove the intersection of two layers

private static final PorterDuff.Mode MODE = PorterDuff.Mode.XOR;



13. PorterDuff. Mode. DARKEN. English description: Take all the regions of the two layers, and deepen the color of the intersection.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.DARKEN;



14. PorterDuff. Mode. LIGHTEN. English description: Take all two layers to light the intersection color.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.LIGHTEN;


15. PorterDuff. Mode. MULTIPLY. English description: color after overlapping the intersection of the two layers

private static final PorterDuff.Mode MODE = PorterDuff.Mode.MULTIPLY;


16. PorterDuff. Mode. SCREEN. Chinese description: Filter color.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.SCREEN;


The following are two newly added models for android:

17. ADD. Description: Saturation addition.

private static final PorterDuff.Mode MODE = PorterDuff.Mode.ADD;


18. OVERLAY. Chinese description: superposition

private static final PorterDuff.Mode MODE = PorterDuff.Mode.OVERLAY;


Download the source code here, Ps: the source code is built in Android Studio.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.