Reference:
Http://www.cnblogs.com/jacktu/archive/2012/01/02/2310326.html
http://blog.csdn.net/yun90/article/details/8618521
Basic knowledge:
1. The following subclass of Xfermode can change this behavior:
AVOIDXFERMODE specifies a color and tolerance, forcing paint to avoid drawing on it (or just drawing on it).
Pixelxorxfermode a simple pixel XOR operation is applied when the existing color is overwritten.
Porterduffxfermode This is a very powerful conversion mode, using it, you can use any of the 16 porter-duff rules of the image composition to control how paint interacts with existing canvas images.
To apply the conversion mode, you can use the Setxfermode method as follows:
Avoidxfermode avoid = new Avoidxfermode (Color.Blue, Avoidxfermode.mode. AVOID); Borderpen.setxfermode (avoid);
2.porter-duff:
3.16 Porter-duff Rules
1.porterduff.mode.clear
The drawing is not submitted to the canvas.
2.porterduff.mode.src
Show Top Draw picture
3.porterduff.mode.dst
Show Lower drawing pictures
4.porterduff.mode.src_over
Normal drawing shows that the upper and lower layers are drawn with overlapping covers.
5.porterduff.mode.dst_over
The upper and lower layers are displayed. The lower level is shown on the home.
6.porterduff.mode.src_in
Draw the intersection of two layers. Displays the upper layer.
7.porterduff.mode.dst_in
Draw the intersection of two layers. Displays the lower layer.
8.porterduff.mode.src_out
Draw the non-intersecting portion of the upper layer.
9.porterduff.mode.dst_out
Remove the layer to draw the non-intersecting part.
10.porterduff.mode.src_atop
Remove the non-intersecting part of the layer from the upper intersection section
11.porterduff.mode.dst_atop
Take the upper non-intersecting part and the lower part of the intersection
12.porterduff.mode.xor
13.porterduff.mode.darken
14.porterduff.mode.lighten
15.porterduff.mode.multiply
16.porterduff.mode.screen
Example 1:
First use the image processing software to create the same shape as the middle yellow area, we will set it as a mask in the code.
Mast Chart
Draw method for view
Public voidDraw (canvas canvas) {//the background part, the graphic aboveBitmap background =Bitmapfactory.decoderesource (Getresources (), r.drawable.guage); //The mask is the part that is extracted.Bitmap mask =Bitmapfactory.decoderesource (Getresources (), r.drawable.mask); Canvas.drawcolor (Color.White); Canvas.drawbitmap (Background,0, 0,NULL); Paint Paint=NewPaint (); Paint.setfilterbitmap (false); intx = 0; inty = 0; //Draw the src/dst example into our offscreen bitmap intsc = Canvas.savelayer (x, y, X + background.getwidth (), Y + background.getheight (),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.drawbitmap (mdstb, 0, 0, paint); canvas.drawrect (0, 0, background.getwidth ()/2 , background. GetHeight (), paint); Paint.setxfermode ( New Porterduffxfermode (PorterDuff.Mode.SRC_IN)); //Canvas.drawbitmap (MSRCB, 0, 0, paint); Canvas.drawbitmap (Mask, 0f, 0f, paint); Paint.setxfermode (null ); Canvas.restoretocount (SC); }
The effect of the progress bar can be achieved only by controlling the length of the drawn rectangle.
Example 2
Set icon to rounded shape in launcher program
PackageCom.example.testsurfaceview;ImportAndroid.annotation.SuppressLint;ImportAndroid.content.Context;ImportAndroid.graphics.Bitmap;Importandroid.graphics.BitmapFactory;ImportAndroid.graphics.Canvas;ImportAndroid.graphics.Color;ImportAndroid.graphics.Paint;ImportAndroid.graphics.PorterDuff.Mode;ImportAndroid.graphics.PorterDuffXfermode;ImportAndroid.graphics.Rect;Importandroid.graphics.drawable.BitmapDrawable;Importandroid.graphics.drawable.Drawable;Importandroid.graphics.drawable.PaintDrawable;ImportAndroid.util.AttributeSet;ImportAndroid.view.SurfaceHolder;ImportAndroid.view.SurfaceHolder.Callback;ImportAndroid.view.SurfaceView; @SuppressLint ("Newapi") Public classCustomsurfaceviewextendsSurfaceviewImplementsCallback { PublicCustomsurfaceview (Context context, AttributeSet attrs,intDefstyleattr,intdefstyleres) { Super(context, Attrs, defstyleattr, defstyleres); Init (); } PublicCustomsurfaceview (context context, AttributeSet attrs,intDefstyle) { Super(context, attrs, Defstyle); Init (); } PublicCustomsurfaceview (Context context, AttributeSet attrs) {Super(context, attrs); Init (); } PublicCustomsurfaceview (Context context) {Super(context); Init (); } Private voidinit () { This. Getholder (). Addcallback ( This); } @Override Public voidsurfacecreated (Surfaceholder holder) {Canvas Canvas=Getholder (). Lockcanvas (); Canvas.drawcolor (Color.White); intW =canvas.getwidth (); inth =canvas.getheight (); Bitmap Bitmap= This. GetIcon ( This. GetContext ()); Bitmap Mat= Bitmapfactory.decoderesource ( This. Getresources (), r.drawable.default_icon_mask); Bitmap= This. Composemat ( This. GetContext (), Bitmap, Mat); intleft = (W-bitmap.getwidth ())/2; inttop = (h-bitmap.getheight ())/2; Canvas.drawbitmap (bitmap, left, top,NewPaint ()); Getholder (). Unlockcanvasandpost (canvas); } @Override Public voidSurfacechanged (Surfaceholder holder,intFormatintwidth,intheight) { //TODO auto-generated Method Stub} @Override Public voidsurfacedestroyed (Surfaceholder holder) {//TODO auto-generated Method Stub } PrivateBitmap GetIcon (Context mcontext) {intWH = (int) mcontext.getresources (). Getdimension (R.DIMEN.ICON_WH); intwidth =WH; intHeight =WH; drawable icon=mcontext.getresources (). getdrawable (R.drawable.ic_launcher); if(Iconinstanceofpaintdrawable) {paintdrawable painter=(paintdrawable) icon; Painter.setintrinsicwidth (width); Painter.setintrinsicheight (height); } Else if(Iconinstanceofbitmapdrawable) { //ensure the bitmap has a density.Bitmapdrawable bitmapdrawable =(bitmapdrawable) icon; Bitmap Bitmap=Bitmapdrawable.getbitmap (); if(bitmap.getdensity () = =Bitmap.density_none) {bitmapdrawable.settargetdensity (Mcontext.getresources (). Getdisplaymetrics ()); } } intSourcewidth =icon.getintrinsicwidth (); intSourceheight =icon.getintrinsicheight (); if(Sourcewidth > 0 && sourceheight > 0) { //there is intrinsic sizes. if(Wh < Sourcewidth | | WH <sourceheight) { //it ' s too big, scale it down. Final floatRatio = (float) Sourcewidth/Sourceheight; if(Sourcewidth >sourceheight) {Height= (int) (Width/ratio); } Else if(Sourceheight >sourcewidth) {Width= (int) (Height *ratio); } } Else if(Sourcewidth < width && Sourceheight <height) { //Don ' t scale up the iconwidth =Sourcewidth; Height=Sourceheight; } } intTexturewidth =WH; intTextureheight =WH; FinalBitmap Bitmap =Bitmap.createbitmap (Texturewidth, Textureheight, Bitmap.Config.ARGB_8888); Canvas Scanvas=NewCanvas (); Scanvas.setbitmap (bitmap); Scanvas.drawcolor (Color.gray); Final intleft = (texturewidth-width)/2; Final inttop = (textureheight-height)/2; Icon.setbounds (left, top, left)+ width, top +height); Rect Soldbounds=NewRect (); Soldbounds.set (Icon.getbounds ()); Icon.setbounds (left, top, left)+ width, top +height); Icon.draw (Scanvas); Icon.setbounds (Soldbounds); Scanvas.setbitmap (NULL); returnbitmap; } Private Static FinalPaint SThemePaint2 =NewPaint (); Private Static FinalAndroid.graphics.Xfermode xfermode_dst_in =NewPorterduffxfermode (mode.dst_in); Private Static FinalAndroid.graphics.Xfermode xfermode_src_in =NewPorterduffxfermode (mode.src_in); PrivateBitmap Composemat (context context, Bitmap SRC, Bitmap mat) {intSiconwidth =mat.getwidth (); intSiconheight =mat.getheight (); FinalBitmap base =Bitmap.createbitmap (Siconwidth, Siconheight, Bitmap.Config.ARGB_8888); Canvas Canvas=NewCanvas (base); Sthemepaint2.setxfermode (NULL);//Canvas.drawrect (New Rect (0, 0, Siconwidth, siconheight), sThemePaint2);//Sthemepaint2.setxfermode (xfermode_src_in); Canvas.drawbitmap (Mat, (Siconwidth-mat.getwidth ())/2, (Siconheight-mat.getheight ())/2, SThemePaint2); Sthemepaint2.setxfermode (xfermode_src_in); Canvas.drawbitmap (SRC, ((siconwidth-src.getwidth ())/2), (Siconheight-src.getheight ())/2 , sThemePaint2); Sthemepaint2.setxfermode (NULL); returnBase; }}
Android Xfermode Porterduffxfermode Implementation Mask Layer