Android Mask Layer Effect

Source: Internet
Author: User

(Analysis with someone else's code) do not know in development is not often used to this effect, so-called mask layer is to give a picture is not the shape we want, this time we can use the mask effect to make this image we want to shape, generally use the most is the round effect, such as:

The above picture is circular, and we this original is square, so we may need such a mask effect to turn it into a circle, this is generally our picture from the network, the shape is not determined by ourselves, so we will add such an effect, look at the following image:

This is a square, so to make a circle, we also need a round full black picture, as follows

This is the picture, in fact, the simple is that two pictures are combined, only show the area covered by the black image, the outside area is not displayed, so as a circular picture (the image above is taken from other applications), In fact, the main technology is related to the use of the Porterduffxfermode class method,

New Porterduffxfermode (PorterDuff.Mode.SRC_IN);

above is the creation of the Porterduffxfermode class , then the parameters inside the PorterDuff.Mode.SRC_IN in fact there are a lot of cases, as if there are up to 16 of the situation, the following describes the commonly used:

PorterDuff.Mode.SRC_IN: Draw the intersection of two layers. Displays the upper layer. is if the above two pictures are stacked, then take the intersection of the two pictures and show the image of the upper layer

PorterDuff.Mode.DST_IN: Draw the intersection of two layers. Displays the lower layer.

Other can be on the internet can be queried, these two use more. Here is another picture of the outer layer of the image of the effect

Okay, now let's see how this code is written.

 PackageCom.example.myimageview;ImportAndroid.content.Context;ImportAndroid.graphics.Bitmap;Importandroid.graphics.BitmapFactory;ImportAndroid.graphics.Canvas;ImportAndroid.graphics.Paint;ImportAndroid.graphics.PorterDuff;ImportAndroid.graphics.PorterDuffXfermode;ImportAndroid.util.AttributeSet;ImportAndroid.view.View; Public classMyimageviewextendsView {Privatecontext Context; PrivateBitmap Bitmapborder; PrivateBitmap Bitmapmask; PrivatePaint paint; PrivatePorterduffxfermode Xfermode; PrivateBitmap Bitmap; Private int_width; Private int_height;  PublicMyimageview (Context context) { This(Context,NULL); }     PublicMyimageview (Context context, AttributeSet attrs) {Super(context, attrs);  This. Context =context; Bitmapborder=Decodebitmap (R.drawable.border); Bitmapmask=Decodebitmap (R.drawable.mask); _width=bitmapborder.getwidth (); _height=bitmapborder.getheight (); Paint=NewPaint (); Xfermode=NewPorterduffxfermode (PorterDuff.Mode.SRC_IN); }     PublicMyimageview (context context, AttributeSet attrs,intDefstyle) {         This(context, attrs); } @Overrideprotected voidOnmeasure (intWidthmeasurespec,intHeightmeasurespec)    {setmeasureddimension (_width, _height); }        PrivateBitmap Decodebitmap (intresId) {        returnBitmapfactory.decoderesource (Context.getresources (), resId); }         Public voidSetresourseid (intResourseid) {Bitmap=Decodebitmap (Resourseid);    Invalidate (); }         Public voidSetresoursebitmap (Bitmap Bitmap) { This. Bitmap =bitmap;    Invalidate (); } @Overrideprotected voidOnDraw (canvas canvas) {if(Bitmap = =NULL){            return; } canvas.drawbitmap (Bitmapborder,0, 0, paint); intSaveFlags = 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.savelayer (0, 0, _width, _height,NULL, SaveFlags); Canvas.drawbitmap (Bitmapmask,0, 0, paint);        Paint.setxfermode (Xfermode); intleft = _WIDTH/2-Bitmap.getwidth ()/2; inttop = _HEIGHT/2-Bitmap.getheight ()/2;        Canvas.drawbitmap (bitmap, left, top, paint); Paint.setxfermode (NULL);    Canvas.restore (); }}

Let's examine the structure of the code:

Myimageview is a subclass of inherited view, in the constructor we see the setting of two pictures Bitmapborder is the bottom of the picture that I posted above, Bitmapmask is that all black round picture, _width and _height is Bitmapborder (The width and height of the peripheral picture), because that picture is the largest we need to define the size of this view so we need this width and height, below

    @Override    protectedvoid onmeasure (intint  Heightmeasurespec) {        setmeasureddimension (_width, _height);    }

is to use width and height to deal with, and we also see the brush paint and porterduffxfermode creation, to illustrate that this Porterduffxfermode object is set by brush paint, the following description

     Public void Setresourseid (int  resourseid) {        = decodebitmap (resourseid);        Invalidate ();    }

This code needs us to manually pass in the picture that we want to turn into a circle, this is set in Avtivity, the most important code to see the OnDraw () method inside.

@Overrideprotected voidOnDraw (canvas canvas) {if(Bitmap = =NULL){            return; } canvas.drawbitmap (Bitmapborder,0, 0, paint); intSaveFlags = 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.savelayer (0, 0, _width, _height,NULL, SaveFlags); Canvas.drawbitmap (Bitmapmask,0, 0, paint);        Paint.setxfermode (Xfermode); intleft = _WIDTH/2-Bitmap.getwidth ()/2; inttop = _HEIGHT/2-Bitmap.getheight ()/2;        Canvas.drawbitmap (bitmap, left, top, paint); Paint.setxfermode (NULL);    Canvas.restore (); }

Let's take a look at three places using Canvas.drawbitmap this method, simple to understand is who first then the picture is displayed at the bottom, the last use of the Drawbitmap () method is displayed on the top

The Canvas.savelayer () method and the Canvas.restore () are paired up,

Canvas can be seen as a canvas in general, with all the drawing operations such as Drawbitmap and drawcircle on this canvas, which also defines properties such as matrix, color, and so on. However, if you need to implement some relatively complex drawing operations, such as multi-layer animation, maps (maps can have multiple layers of map overlay, such as: Political district, road layer, point of interest layer). Canvas provides layer support, which, by default, can be thought of as having only one layer of layers. If you need to draw at a level, Android canvas can use Savelayerxxx, Restore to create some middle layers, which are managed according to the "Stack structure":

Create a new layer to "stack", you can use Savelayer, Savalayeralpha, from the "stack" to roll out a layer, you can use Restore,restoretocount. However, when the layer is in the stack, subsequent drawxxx operations occur on the layer, and when the layer is retired, it will "draw" the image drawn at the level to the top or canvas, and when you copy the layer to the canvas, you can specify the layer's transparency (layer) , which is specified when creating a layer: public int savelayeralpha (RECTF bounds, int alpha, int saveflags);

Specific points can be http://blog.csdn.net/linghu_java/article/details/8939952 this site to understand.

Paint.setxfermode (Xfermode); This is the effect of setting the brush, left and top needless to say is the picture to be displayed in the center of the position. Canvas.drawbitmap (bitmap, left, top, paint); This is the last Canvas.drawbitmap method, and the PorterDuff.Mode.SRC_IN parameter is used, which means draw the intersection of two layers. Display the upper layer , that is, the last picture is displayed.

In fact, from the above look at the effect is good, but in the real application we can not be difficult to find some pictures may be very large, this time we need to compare the image of the amplification effect

http://bbs.csdn.net/topics/310218516 this URL to see the introduction of such as the zoom image of the example, we look at the following picture effect

The above two graphs contrast, the first one is the original effect, the second one is to the image of the zoom effect, see the second picture code:

 PackageCom.example.myimageview;ImportAndroid.content.Context;ImportAndroid.graphics.Bitmap;Importandroid.graphics.BitmapFactory;ImportAndroid.graphics.Canvas;ImportAndroid.graphics.Paint;ImportAndroid.graphics.PorterDuffXfermode;ImportAndroid.graphics.RectF;ImportAndroid.graphics.PorterDuff.Mode;ImportAndroid.util.AttributeSet;ImportAndroid.view.View; Public classItchqimageviewextendsview{PrivateBitmap BG; PrivateBitmap photo; Private intBg_width; Private intBg_height;  PublicItchqimageview (Context context, AttributeSet attrs) {Super(context, attrs); //TODO auto-generated Constructor stubinit (); }        Private voidinit () {BG=Bitmapfactory.decoderesource (Getresources (), r.drawable.mask); Bg_width=bg.getwidth (); Bg_height=bg.getheight (); }     Public voidSetimageview (intImgid) {Photo=Bitmapfactory.decoderesource (Getresources (), imgid);    Scaleimage (); } @Overrideprotected voidOnDraw (canvas canvas) {//TODO auto-generated Method Stub        Super. OnDraw (canvas); Paint Paint=NewPaint (Paint.anti_alias_flag); Paint.setxfermode (NewPorterduffxfermode (mode.dst_in)); RECTF RECTF=NewRECTF (0,0, Bg_width,bg_height); Canvas.savelayer (RECTF,NULL, Canvas.all_save_flag); Canvas.drawbitmap (Photo,0,0,NULL); Canvas.drawbitmap (BG,0, 0, paint);    Canvas.restore (); }        Private voidScaleimage () {if(photo!=NULL){                        intwidht=photo.getwidth (); intheight=photo.getheight (); intNew_width=0; intNew_height=0; if(widht!=height) {                if(widht>height) {New_height=Bg_height; New_width=widht*new_height/height; }Else{new_width=Bg_width; New_height=height*new_width/widht; }            }Else{new_width=Bg_width; New_height=Bg_height; } Photo= Bitmap.createscaledbitmap (photo, New_width, New_height,true); }    }    }
scaleimage() This method is in the image to do the same scaling effect, the size of the scale is the same as our full black picture size (here we originally outside the round effect is removed, is the third Zhangquan white picture above)
If the picture is not square, we need to judge the contrast, and the final width and height is that we have to wait than the size of the scale.

Android Matte Layer effect

Related Article

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.