Vegetable Chicken Wing Encounter enemy porterduffxfermode, unexpectedly too underestimate, struggling. Then with the war three days and three nights, more than 300 rounds dead heat. Kidnap @ Mimi Control help, Lucky win.
Keyword: porterduffxfermode error incorrect does not reach expected bug
Porterduffxfermode always fail to perform as expected. The error of Porterduffxfermode is a very deep hole for beginners, in the end is a bug, or there is a need to pay attention to the place. Here, follow me with a flashlight to find out.
Reprint Please specify source: http://blog.csdn.net/wingichoy/article/details/50534175
First of all, we all know that there is a picture:
And then, most of the time, it's amazing to see that, especially src_in and dstin can achieve masking effects, such as rounded picture round pictures.
Therefore, each model is tested to be effective, and the results often fail to achieve the desired effect . Let's do a test.
From the simplest of beginnings:
1. Draw the graphic directly above the canvas :
@Override protected void OnDraw (canvas canvas) { //dst canvas.drawrect (20,20,80,80,mdstpaint); SRC canvas.drawcircle (30,30,30,msrcpaint); }
The original effect is this:
Now add a mode up, XOR
@Override protected void OnDraw (canvas canvas) { //dst canvas.drawrect (20,20,80,80,mdstpaint); Msrcpaint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.XOR)); SRC canvas.drawcircle (30,30,30,msrcpaint); }
The result of the run is this:
wtf!!?? What the hell is this? It should not be the intersect part disappears. The internet says " hardware acceleration " has an effect on this, so turn off hardware acceleration in the constructor to try it out:
Public TestView (context context, AttributeSet attrs, int defstyleattr) { Super (context, attrs, defstyleattr); Mdstpaint = new Paint (); Msrcpaint = new Paint (); Mdstpaint.setcolor (color.yellow); Msrcpaint.setcolor (Color.Blue); Setlayertype (view.layer_type_software, null); }
Results of the operation:
It's normal. The intersecting parts are gone.
Conclusion 1: Hardware acceleration has an effect on Porterduffxfermode, please turn off hardware acceleration before use.
So is it really all right? Nonono~ not too naïve, otherwise how can call abyss it.
Continue experimenting with other modes: Change mode to Src_in
WTF????? It's not consistent with the fundamental. Try the dst_in.
Are you sure you're not kidding me???? How is this a ghost thing. (At that time to tinker with me three days four nights, has been in the day dog, but first don't hurry, slowly.) )
Why must you follow that? Because the map of special is an official demo. So let's see what this demo looks like!
Package Io.appium.android.apis.graphics;import Android.content.context;import Android.graphics.bitmap;import Android.graphics.bitmapshader;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.matrix;import Android.graphics.paint;import Android.graphics.porterduff;import Android.graphics.porterduffxfermode;import Android.graphics.rectf;import Android.graphics.shader;import Android.graphics.xfermode;import Android.os.bundle;import Android.view.view;public class Xfermodes extends graphicsactivity {//Create a bitmap with a circle, used for the "DST" image static 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 with a rect, used for the "src" image static 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 OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (New Sampleview (this)); } private static Class Sampleview extends View {private static final int W = 64; private static final int H = 64; private static final int row_max = 4; Number of samples per row private Bitmap MSRCB; Private Bitmap Mdstb; Private Shader MBG; Background Checker-board pattern private static final xfermode[] Smodes = {New Porterduffxfermode (Po RterDuff.Mode.CLEAR), New Porterduffxfermode (PorterDuff.Mode.SRC), New Porterduffxfermode (Porterduff . MODE.DST), New PORTERDUFFXFErmode (PorterDuff.Mode.SRC_OVER), New Porterduffxfermode (PorterDuff.Mode.DST_OVER), new PORTERDUFFXF Ermode (PorterDuff.Mode.SRC_IN), New Porterduffxfermode (PorterDuff.Mode.DST_IN), new Porterduffxfermo De (PorterDuff.Mode.SRC_OUT), New Porterduffxfermode (PorterDuff.Mode.DST_OUT), new Porterduffxfermode (PorterDuff.Mode.SRC_ATOP), New Porterduffxfermode (PorterDuff.Mode.DST_ATOP), new Porterduffxfermode (PorterDuff.Mode.XOR), New Porterduffxfermode (PorterDuff.Mode.DARKEN), New Porterduffxfermode (Porter Duff.Mode.LIGHTEN), New Porterduffxfermode (PorterDuff.Mode.MULTIPLY), New Porterduffxfermode (Porterd Uff. Mode.screen)}; private static final string[] Slabels = {"Clear", "SRC", "DST", "Srcover", "Dstover", "Srcin", "DST In "," Srcout "," Dstout "," Srcatop "," Dstatop "," Xor "," darken "," lighten "," Multiply "," ScReen "}; Public Sampleview (Context context) {super (context); MSRCB = Makesrc (W, H); MDSTB = MAKEDST (W, H); Make a ckeckerboard pattern Bitmap BM = Bitmap.createbitmap (new int[] {0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCCCC, 0xFFFFFFFF}, 2, 2, Bitmap.Config.RG b_565); MBG = new Bitmapshader (BM, Shader.TileMode.REPEAT, Sha Der. Tilemode.repeat); Matrix M = new Matrix (); M.setscale (6, 6); Mbg.setlocalmatrix (m); } @Override protected void OnDraw (canvas canvas) {canvas.drawcolor (color.white); Paint labelp = new paint (Paint.anti_alias_flag); Labelp.settextalign (Paint.Align.CENTER); Paint paint = new paint (); Paint.setfilterbitmap (FALSE); Canvas.translate (15, 35); int x = 0; int y = 0; for (int i = 0; i < smodes.length; i++) {//Draw the Border Paint.setstyle (paint.style.s Troke); Paint.setshader (NULL); Canvas.drawrect (x-0.5f, y-0.5f, x + W + 0.5f, y + H + 0.5f, paint); Draw the Checker-board pattern Paint.setstyle (Paint.Style.FILL); Paint.setshader (MBG); Canvas.drawrect (x, y, x + W, y + H, paint); Draw the SRC/DST example into our offscreen bitmap int sc = canvas.savelayer (x, y, x + W, y + H, 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); Canvas.translate (x, y); Canvas.drawbitmap (mdstb, 0, 0, paint); Paint.setxfermode (Smodes[i]); Canvas.drawbitmap (MSRCB, 0, 0, paint); Paint.setxfermode (NULL); Canvas.restoretocount (SC); Draw the label Canvas.drawtext (Slabels[i], x + W/2, Y-labelp.gettextsiz E ()/2, labelp); X + = W + 10; Wrap around when we ' ve drawn enough for one row if ((i% row_max) = = row_max-1) {x = 0; Y + = H + 30; } } } }}
At 1.1 o ' OnDraw, intercept the fragments inside the
Canvas.drawbitmap (mdstb, 0, 0, paint); Paint.setxfermode (Smodes[i]); Canvas.drawbitmap (MSRCB, 0, 0, paint); Paint.setxfermode (NULL);
He has painted two bitmap. Some people on the internet say that it seems to be only effective for bitmap. Let's test it out.
We define a new canvas and then define a bitmap now bitmap on the SRC and then draw the bitmap onto the canvas:
Public TestView (context context, AttributeSet attrs, int defstyleattr) { Super (context, attrs, defstyleattr); Mdstpaint = new Paint (); Msrcpaint = new Paint (); Mdstpaint.setcolor (color.yellow); Msrcpaint.setcolor (Color.Blue); Setlayertype (view.layer_type_software, null); Msrcbitmap = Bitmap.createbitmap (50,50, Bitmap.Config.ARGB_8888); Mcanvas = new Canvas (MSRCBITMAP); }
@Override protected void OnDraw (canvas canvas) { //dst canvas.drawrect (20,20,80,80,mdstpaint); src// Msrcpaint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.DST_IN)); Mcanvas.drawcircle (25,25,25,msrcpaint); Canvas.drawbitmap (Msrcbitmap,0,0,null); }
Now the effect is this:
Add an XOR to try it out.
It's a dog,!!!!!. No response ah, what the hell.
is not two need bitmap to do, and then create a dstbitmap and Dstcanvas?
Mdstbitmap = Bitmap.createbitmap (50,50, Bitmap.Config.ARGB_8888); Mdstcanvas = new Canvas (MDSTBITMAP);
Plus an XOR try
@Override protected void OnDraw (canvas canvas) { //dst mdstcanvas.drawrect (20,20,80,80,mdstpaint); Canvas.drawbitmap (mdstbitmap,0,0,mdstpaint); SRC msrcpaint.setxfermode (new Porterduffxfermode (PorterDuff.Mode.XOR)); Msrccanvas.drawcircle (25,25,25,msrcpaint); Canvas.drawbitmap (Msrcbitmap,0,0,msrcpaint); }
The effect is as follows:
Finally fucking out!!!! What about the other effects?
Clear
The same!!!! Good excitement there is no!!! 4 days getting closer to the conclusion!!!
Conclusion 2: Only two bitmap can take effect.
Don't be happy too early. If the pit is finished here, it's still called a pit.
Keep trying. Well, a lot of patterns are consistent.
Until!!! Src_in and dst_in, will find ... Are gone. For woolen??
Check code Discovery Set the mode before you go to bitmap to draw a circle.
Correct
@Override protected void OnDraw (canvas canvas) { //dst mdstcanvas.drawrect (20,20,80,80,mdstpaint); Canvas.drawbitmap (mdstbitmap,0,0,mdstpaint); SRC msrccanvas.drawcircle (25,25,25,msrcpaint); After drawing the circle, set Mode msrcpaint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.XOR)); Canvas.drawbitmap (Msrcbitmap,0,0,msrcpaint); }
Found
艹!!!!!! Well, finally,!!!!!!!!. After unremitting efforts!!! Sprinkle the flowers! *★,°*:.☆\ ( ̄▽ ̄)/$:*. °★*.
In fact, we just bitmap the same size. And then all from 0, 0 started completely covered.
So stagger a little bit is what effect, adjust the code as follows
protected void OnDraw (canvas canvas) { //dst mdstcanvas.drawrect (20,20,80,80,mdstpaint); Canvas.drawbitmap (mdstbitmap,20,20,mdstpaint); SRC msrccanvas.drawcircle (25,25,25,msrcpaint); Msrcpaint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.SRC_IN)); Canvas.drawbitmap (Msrcbitmap,0,0,msrcpaint); }
The effect is as follows:
can see the effect!!!! But what a ghost!!! Rectangular angle of absence?? Add a little blue??
It's hard to see the effect in this way. To adjust the bitmap and the size of the rectangle:
The two bitmap of the background are painted gray, the rectangle does not occupy the canvas to set aside space
Mdstcanvas.drawcolor (Color.gray);
@Override protected void OnDraw (canvas canvas) { //dst yellow mdstcanvas.drawrect (0,0,40,40,mdstpaint) ; Canvas.drawbitmap (mdstbitmap,20,20,mdstpaint); SRC Blue msrccanvas.drawcircle (25,25,25,msrcpaint); Canvas.drawbitmap (Msrcbitmap,0,0,msrcpaint); }
The effect is as follows: Well, that's two bitmap. Very clear bitmap content location,
and then src_in mode.
Dst_in
Then remove the bitmap background. Change to Transparent?
Dst_in:
Src_in:
Summary 3: Two bitmap position does not completely overlap the effect as above, and can not summarize the effect, to the actual effect.
---------------------------------------------------------------------------------------------------------Gorgeous split-line--------- --------------------------------------------------------------------------------
Finally, if you want the Porterduffxfermode to be implemented as expected by the demo (or), the following conditions must be met:
1. Turn off hardware acceleration.
2, the size of two bitmap as much as possible.
3, the background color is transparent color.
4, if the two bitmap position is not exactly the same, may also be expected effect, but you see the effect and your own brain complement the expected effect is inconsistent.
Finally, I would like to say a few words. Tinker with this pattern for almost a week and work out every night. A lot of information was checked. But a lot of incomplete, even some misleading. So in order to avoid the later people into the pits. Test it yourself and summarize it as much as possible. If there is something wrong, please ask me in time. I will correct it in time.
If this article helps you, please point a top, or comment, crab!!!!
There's a hole?? Why wing fell into Porterduffxfermode's Abyss (Porterduffxfermode in-depth test)