Android image processing--paint Xfermode

Source: Internet
Author: User

Reprint Please specify source:http://blog.csdn.net/allen315410/article/details/45077165

In my previous blog, I summed up several subclasses and usages of colorfilter related to paint, the most commonly used colormatrixcolorfilter worth learning, by defining a color-valued 4*5 matrix, To set the various discoloration effects of paint. In addition, there are porterduffcolorfilter, it is not a lot of practical, but the use of several concepts in Porterduffcolorfilter is particularly important, we have to understand, Porterduff is a foreigner invented the pattern of mixed mode, And the Android API provides us with 18 different mixed-mode algorithms, we usually need to understand the development of these patterns represent the meaning and usage, is the flexibility to use these patterns randomly mix the image effects we need.


Xfermode

Xfermode specifically how to translate, to tell the truth, I do not know, I am accustomed to call it picture mixed mode, casually, whatever it is called, does not hinder our use of it. A description of Xfermode can be found in Google Docs: Xfermode is the base class for customizing "Transfer Mode" in the drawing channel. A static function creation can invoke or return any predefined subclass instance specified as a pattern enumeration. When Xfermode is assigned to paint, then the object is drawn with the paint to have the added Xfermode. Read more mouthful, the following directly see Xfermode Source:

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 so little code, experience tells us, it must have sub-category, Rub, Yuan Fang ~ ~ ~

Take a look at the document Discovery Xfermode do have Avoidxfermode, Pixelxorxfermode, Porterduffxfermode, and continue to learn about the usage of 3 subclasses.


Avoidxfermode look at this sub-class before telling everyone a sad news, Avoidxfermode does not support hardware acceleration, on the machine above API16 will not apply, if you want to test this subclass, 1, you can turn off the phone hardware accelerator module; 2, Set the hardware acceleration to false on the application node in Androidmanifest.xml.

Android:hardwareaccelerated= "false"
Click to see how Avoidxfermode is constructed under Android Studio:

Public Avoidxfermode (int opcolor, int tolerance, mode mode)
The construction method of the Avoidxfermode is also very simple, receiving a total of 3 parameters: the first parameter opcolor is a 16-based color value with a transparency channel, such as 0x12345678. The second parameter, tolerance, represents the tolerance value, what is the tolerance value? Can be understood as a concept that represents "precision" and "blur", as explained below. The third parameter is the Avoidxfermode pattern, with a total of two types of Avoidxfermode: AvoidXfermode.Mode.TARGET and AvoidXfermode.Mode.AVOID.


AvoidXfermode.Mode.TARGET in this mode, Android will determine whether the color on the canvas will be different from opcolor color, such as I opcolor is red, then in the target mode will be judged whether there is a red place on our canvas, if there is, then the area The field "dye" on a layer of our brush-defined color, otherwise not "dyed" color, and the tolerance tolerance value indicates the difference between the pixel on the canvas and our defined red is how much time to "dye", such as the current canvas has a pixel color value is (200, 20, 13), and our red value is ( 255, 0, 0), when the tolerance tolerance value is 255, even (200, 20, 13) is not equal to the red value will also be "dyed" color, the greater the tolerance value "dye" color range the more the opposite is reversed, empty say no by we look at the specific implementation and effect:

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.M        Ipmap.image);        Gets the presentation start layout of bitmap 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 (0XFFFFFFFF, 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); }}
To see the effect below, first make sure that the emulator that is turned on is API16 below, or the application node is set to turn off hardware acceleration:

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

As you can see, in our mode the target tolerance value is 0, and only when the image has a color value of 0XFFFFFFFF will be dyed, and the other places will not change

Let's modify the tolerance value to change the tolerance value to 255:


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

And when the tolerance value is 255, it will be dyed if it's a bit close to the 0XFFFFFFFF.


AvoidXfermode.Mode.AVOID is the opposite of target, Target is the color we specify is the same as the color of the canvas, and avoid is the color we specify is not the same as the canvas, others are similar to target
Avoidxfermode (0XFFFFFFFF, 0, AvoidXfermode.Mode.AVOID):

When the mode is a avoid tolerance of 0 o'clock, only if the pixel color value in the picture is exactly the same as the 0XFFFFFFFF, it will be dyed.
Avoidxfermode (0XFFFFFFFF, 255, AvoidXfermode.Mode.AVOID):


When the tolerance value is 255, it will be dyed as long as it is slightly different from the 0XFFFFFFFF.
So what's the use of this thing? For example, when we just want to draw something in the white area or want to replace the white area with another picture, we can do it this way!


Pixelxorxfermode

Pixelxorxfermode is another kind of image mixed mode under Xfermode, this class is very simple, but, unfortunately, in the API16 is outdated. Let's start with a simple understanding of how Pixelxorxfermode is constructed:

The construction method is very simple, just pass a 16-input with transparent channel color value can, then what is the use of this parameter? In my Google docs, I found an algorithm that actually pixelxorxfermode internally is based on the XOR algorithm of "Opcolor ^ src ^ dst", getting an opaque (alpha = 255) color value, set to the image, Below we then use the above image demo to write a Pixelxorxfermode demo:

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.M        Ipmap.image);        Gets the presentation start layout of bitmap 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,src Canvas.drawbitmap First (Mbitmap, x, Y, MP        aint);        Randomly set a solid color test Mpaint.setargb (255, 211, 53, 243);        Set Xfermode Mpaint.setxfermode (Pixelxorxfermode);    Mix a solid color rectangle (DST) canvas.drawrect (x, Y, W, H, Mpaint) on bitmap; }}
The image after the mix is:

The Pixelxorxfermode has been removed at the bottom src,dst each pixel is opcolor ^ src ^ dst operation with Opcolor, and the result output is as shown! Well, I only learn so much, because it is outdated, the same avoidxfermode also, outdated, understand. The following is the third subclass of Xfermode, and the only one that is not outdated, very important subclass Porterduffxfermode learning.

Porterduffxfermode the same Porterduffxfermode is also a subclass of Xfermode, let's first look at its construction method:
Public Porterduffxfermode (Porterduff.mode Mode)
The construction method of Porterduffxfermode is very simple, The construction method needs to pass a porterduff.mode parameter, about Porterduff.mode, we have learned in the previous blog, in fact, with the Colorfilter sub-class Porterduffcolorfilter mixed pattern is the same. The Android system provides a total of 18 mixed-mode, in the simulator's apidemos/graphics/xfermodes, there is Zhang: This picture can be very graphic description of the image of various mixed-mode effects. where SRC represents the original picture, DST represents the target graph, and the two images use different blending methods after the resulting image is as shown. Porterduff.mode also provides 18 kinds of mixed-mode algorithms, which are more than the add and overlay two modes: where the SA is all called Source Alpha, which represents the origin of the alpha channel; SC is all called source color. The DA is all called Destination Alpha, which represents the alpha channel of the target graph; the DC is all called destination color, which represents the colors of the target graph [...,..] The first half calculates the alpha channel value of the resulting image, and the second half calculates the color value of the resulting image. After the image is mixed with these two values to recalculate the ARGB value, the specific calculation algorithm, sorry, I do not know, but it does not matter, do not understand the calculation algorithm does not affect our programmer to write programs. We can infer the results of the mixed rows by comparing the pictures provided in the above Apidemo, the following will be modified against the Apidemos/graphics/xfermodes program to test the effect of each module, the test procedure is as follows:
public class Xfermodeview extends View {//porterduff mode constants can be changed here in different modes test private static final Porterduff.mode mode =    PorterDuff.Mode.CLEAR;    Private Porterduffxfermode Porterduffxfermode; private int screenw, screenh;    Wide screen height private Bitmap srcbitmap, Dstbitmap;    Source and target plot width 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 Porterduffxfermode object porterduffxfermode = new Porterduffxfermode (MODE);        Create original and target graphs Srcbitmap = makesrc (width, height);    Dstbitmap = makedst (width, height); }//Create a circular Bitmap, as the DST diagram private Bitmap makedst (int w, int h) {Bitmap BM = Bitmap.createbitmap (W, H, bitmap.c Onfig.        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 rectangle Bitmap, as src diagram 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 "src" Blue Rectangle original Canvas.drawbitmap (Srcbitmap, SCREENW/8-WIDTH/4, SCREENH/12-HEIGHT/4, paint);        Draw the "DST" yellow round artwork Canvas.drawbitmap (Dstbitmap, SCREENW/2, SCREENH/12, paint); Create a layer to demonstrate the effect of blending the shape 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);        First draw "DST" yellow round Canvas.drawbitmap (Dstbitmap, SCREENW/4, SCREENH/3, paint);        Set the Xfermode Paint.setxfermode (porterduffxfermode) of the paint;        Canvas.drawbitmap (Srcbitmap, SCREENW/4, SCREENH/3, paint);        Paint.setxfermode (NULL);    Restore Canvas Canvas.restoretocount (SC); }}
For ease of observation, you need to set the background color of the activity_main.xml to black.

1.porterduff.mode.clear. Description: The drawn source image is not submitted to the canvas.

private static final Porterduff.mode Mode = PorterDuff.Mode.CLEAR;


2.porterduff.mode.src. Description: Only the source image is displayed.

private static final Porterduff.mode Mode = PorterDuff.Mode.SRC;



3.porterduff.mode.dst. Description: Displays only the target image.

private static final Porterduff.mode Mode = PorterDuff.Mode.DST;


4.porterduff.mode.src_over. Chinese description: Normal drawing display, the source image on the display.

private static final Porterduff.mode Mode = PorterDuff.Mode.SRC_OVER;



5.porterduff.mode.dst_over. English Description: The upper and lower layers are displayed. The target image is displayed on the home.

private static final Porterduff.mode Mode = PorterDuff.Mode.DST_OVER;



6.porterduff.mode.src_in. English Description: Take two layers to draw the source image of the intersection.

private static final Porterduff.mode Mode = PorterDuff.Mode.SRC_IN;



7.porterduff.mode.dst_in. English Description: Take two layers to draw the target image of the intersection.

private static final Porterduff.mode Mode = PorterDuff.Mode.DST_IN;



8.porterduff.mode.src_out. Description: Draws the source image only where the source and destination images do not intersect.

private static final Porterduff.mode Mode = PorterDuff.Mode.SRC_OUT;



9.porterduff.mode.dst_out. Description: Draws the target image only where the source image and the target image do not intersect.

private static final Porterduff.mode Mode = PorterDuff.Mode.DST_OUT;



10.porterduff.mode.src_atop. Description: Draws the source image where the source and destination images intersect, and draws the target image where it does not intersect.

private static final Porterduff.mode Mode = PorterDuff.Mode.SRC_ATOP;



11.porterduff.mode.dst_atop. Description: Draws the target image where the source image and destination image intersect, and draws the source image where it does not intersect.

private static final Porterduff.mode Mode = PorterDuff.Mode.DST_ATOP;



12.porterduff.mode.xor. Description: Xor: Remove the two Layer intersection section

private static final Porterduff.mode Mode = PorterDuff.Mode.XOR;



13.porterduff.mode.darken. English Description: Take two layers of all areas, the intersection part of the color deepened

private static final Porterduff.mode Mode = PorterDuff.Mode.DARKEN;



14.porterduff.mode.lighten. Description: Take two layers all, light the intersection part color

private static final Porterduff.mode Mode = PorterDuff.Mode.LIGHTEN;


15.porterduff.mode.multiply. English Description: Take two layer intersection part overlay color

private static final Porterduff.mode Mode = PorterDuff.Mode.MULTIPLY;


16.porterduff.mode.screen. Description: Color filter.

private static final Porterduff.mode Mode = PorterDuff.Mode.SCREEN;


The following are the two new modes in Android:

17.ADD. Description: The addition of saturation.

private static final Porterduff.mode Mode = PorterDuff.Mode.ADD;


18.OVERLAY. English Description: Overlay

private static final Porterduff.mode Mode = PorterDuff.Mode.OVERLAY;


source code Please download here , PS: Source code is built in Android studio.


Android image processing--paint Xfermode

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.