Screenshot implementation for Android custom regions

Source: Internet
Author: User
Tags gety

The implementation in a recent project has implemented many functions, but there is not much nonsense.

Before

After


Implementation principle:
1. Get the full screen
View view = activity. getwindow (). getdecorview ();
View. setdrawingcacheenabled (true );
View. builddrawingcache ();
Bitmap b1 = view. getdrawingcache ();

2. Use the full screen as the background image of surfaceview. (Or set surfaceview with transparent background)
In the current area, determine the user's click to slide (draw a rectangle, pan, stretch) to get the rectangle finally drawn by the user.
The specific processing is complicated. For details, see event processing in shotview.

3. Extract the image to be captured from the image obtained in step 1.
Savebitmap = bitmap. createbitmap (shotview. This. bitmap, rect. Left, rect. Top, rect. Width (), rect. Height ());

The main implementation classes are as follows:

Package COM. eebbk. view; import COM. eebbk. activity. r; import android. app. alertdialog; import android. content. context; import android. graphics. bitmap; import android. graphics. canvas; import android. graphics. color; import android. graphics. paint; import android. graphics. paintflagsdrawfilter; import android. graphics. path; import android. graphics. pixelformat; import android. graphics. point; import android. graphics. re CT; import android. graphics. paint. style; import android. util. attributeset; import android. util. log; import android. view. gravity; import android. view. keyevent; import android. view. layoutinflater; import android. view. motionevent; import android. view. surfaceholder; import android. view. surfaceview; import android. view. view; import android. view. viewgroup. layoutparams; import android. widget. imageview; import android. Widget. popupwindow; import android. widget. toast; import static COM. eebbk. util. calc. getpointdis; public class shotview extends surfaceview implements surfaceholder. callback, runnable {Private Static final int rad = 5; private paint; private surfaceholder sh; private Boolean isrunning = true; private canvas; private Bitmap bitmap = NULL; private rect; private point [] points = new point [8]; PR Ivate point startpoint; private point endpoint; private Path; private popupwindow; private bitmap savebitmap; // draw the status flag of the rectangle 0 not start 1 complete 2 modify 3 translate private int drawstate = 0; // modify the vertex private int Index =-1; public void setisrunning (Boolean B) {// todo auto-generated method stubthis. isrunning = B;} public void setbitmap (Bitmap bitmap) {This. bitmap = bitmap;} public bitmap getbitmap () {return bitm AP;} public shotview (context) {super (context); // todo auto-generated constructor stubinit ();} public shotview (context, attributeset attrs) {super (context, attrs); // todo auto-generated constructor stubinit ();} private void Init () {// The comments are transparent canvas effects. // setzorderontop (true); paint = new paint (); SH = This. getholder (); SH. addcallback (this); // sh. setformat (pixelformat. translucent); rect = New rect (); startpoint = new point (); endpoint = new point (); Path = New Path (); this. setfocusable (true) ;}@ overridepublic void surfacecreated (surfaceholder holder) {// todo auto-generated method stubnew thread (this ). start () ;}@ overridepublic void surfacechanged (surfaceholder holder, int format, int width, int height) {// todo auto-generated method stub} @ overridepublic void surfacedestroye D (surfaceholder holder) {// todo auto-generated method stubisrunning = false; try {thread. sleep (300);} catch (interruptedexception e) {// todo auto-generated catch blocke. printstacktrace () ;}@ overridepublic Boolean ontouchevent (motionevent event) {Switch (event. getaction () {Case motionevent. action_down: system. out. println ("down"); point downpoint = new point (INT) event. getx (), (INT) E Vent. Gety (); Index = checkdownpoint (downpoint); If (drawstate = 1 & Index! =-1) {// if you click four vertices if (Index = 0 | Index = 2 | Index = 5 | Index = 7) {// specifies the vertex in the vertex. Select the diagonal vertex as the drawing start point (similar to the start drawing, so do not change drawstate) startpoint = points [7-Index];} else if (Index = 1 | Index = 3 | Index = 4 | Index = 6) {drawstate = 2;} else if (Index = 8) {// translate drawstate = 3; startpoint = downpoint ;}} else {startpoint = downpoint;} path. moveTo (event. getx (), event. gety (); break; Case motionevent. action_m Ove: path. lineto (event. getx (), event. gety (); endpoint. X = (INT) event. getx (); endpoint. y = (INT) event. gety (); int left = 0; int Top = 0; int right = 0; int Bottom = 0; // after the first painting or painting, change the four vertices for the second time. If (drawstate = 0 | drawstate = 1) {left = math. min (startpoint. x, endpoint. x); Top = math. min (startpoint. y, endpoint. y); Right = math. max (startpoint. x, endpoint. x); bottom = math. max (startpoint. y, Endpoint. y); rect. set (left, top, right, bottom);} // The second time you modify the vertex else if (drawstate = 2) on the edge) {// if you click the midpoint of the rectangle WIDTH If (Index = 1 | Index = 6) {Top = points [index-1]. y; bottom = points [index + 1]. y; left = math. min (points [7-Index]. x, endpoint. x); Right = math. max (points [7-Index]. x, endpoint. x);} // click the long vertex else if (Index = 3 | Index = 4) {left = points [index-2]. x; Right = points [index + 2]. X; Top = math. min (points [7-Index]. y, endpoint. y); bottom = math. max (points [7-Index]. y, endpoint. y);} rect. set (left, top, right, bottom);} // You can pan the drawn quadrilateral else if (drawstate = 3) {int dx = endpoint. x-startpoint. x; int DY = endpoint. y-startpoint. y; // move the rectangular box if (rect. left> 0 & rect. right <getwidth () & rect. top> 0 & rect. bottom <getheight () {// If the rectangle goes out after this step, do not move if (! (Rect. left + dx> 0 & rect. right + DX <getwidth () & rect. top + dy> 0 & rect. bottom + dy <getheight () {break;} rect. offset (dx, Dy); startpoint. X = endpoint. x; startpoint. y = endpoint. y;} system. out. println (rect);} break; Case motionevent. action_up: log. I ("motionevent. action_up ", event. getx () + "" + event. gety (); If (popupwindow! = NULL) {popupwindow. dismiss (); popupwindow = NULL;} drawstate = 1; view = layoutinflater. from (getcontext ()). inflate (R. layout. popwindow_confirm, null); popupwindow = new popupwindow (view, layoutparams. wrap_content, layoutparams. wrap_content); popupwindow. setoutsidetouchable (true); popupwindow. showatlocation (this, gravity. left | gravity. top, rect. right, rect. bottom); setpoplistener (view); Break;} return true;} // check whether the down point is on the rect key point. If-1 is returned, the indexprivate int checkdownpoint (point downpoint) of the down point is returned) {// todo auto-generated method stubpoints [0] = new point (rect. left, rect. top); points [1] = new point (rect. left, (rect. top + rect. bottom)/2); points [2] = new point (rect. left, rect. bottom); points [3] = new point (rect. left + rect. right)/2, rect. top); points [4] = new point (R ECT. left + rect. right)/2, rect. bottom); points [5] = new point (rect. right, rect. top); points [6] = new point (rect. right, (rect. top + rect. bottom)/2); points [7] = new point (rect. right, rect. bottom); For (INT I = 0; I <points. length; I ++) {If (getpointdis (points [I], downpoint) <3 * rad) {return I ;}} if (downpoint. x> rect. left & downpoint. x <rect. right & downpoint. y> rect. top & do Wnpoint. Y <rect. bottom) {return 8;} return-1;} private void setpoplistener (view) {// todo auto-generated method stubpopupwindow. getcontentview (). setontouchlistener (new view. ontouchlistener () {@ overridepublic Boolean ontouch (view V, motionevent event) {If (event. getaction () = motionevent. action_outside) {system. out. println ("click the external button and destroy it !!! "); Popupwindow. dismiss (); popupwindow = NULL;} return true ;}}); view. findviewbyid (R. id. cancle_ll ). setonclicklistener (New onclicklistener () {@ overridepublic void onclick (view v) {// todo auto-generated method stubtoast. maketext (getcontext (), "Repeat! ", Toast. length_short). Show (); rect. setempty (); invalidate (); If (popupwindow! = NULL) {popupwindow. dismiss (); popupwindow = NULL ;}}); view. findviewbyid (R. id. back_ll ). setonclicklistener (New onclicklistener () {@ overridepublic void onclick (view v) {// todo auto-generated method stubtoast. maketext (getcontext (), "Return to the original view! ", Toast. length_short). Show (); rect. setempty (); invalidate (); If (popupwindow! = NULL) {popupwindow. dismiss (); popupwindow = NULL;} isrunning = false; setvisibility (view. invisible) ;}}); view. findviewbyid (R. id. OK _ll ). setonclicklistener (New onclicklistener () {@ overridepublic void onclick (view v) {// todo auto-generated method stubtoast. maketext (getcontext (), "done! ", Toast. length_short ). show (); savebitmap = bitmap. createbitmap (shotview. this. bitmap, rect. left, rect. top, rect. width (), rect. height (); imageview imgview = new imageview (getcontext (); imgview. setimagebitmap (savebitmap); New alertdialog. builder (getcontext ()). settitle ("captured image "). setview (imgview ). setpositivebutton ("OK", null ). show () ;}}) ;}@ overridepublic void run () {// todo auto-generated Method stubwhile (isrunning) {drawview (); try {thread. sleep (100);} catch (interruptedexception e) {// todo auto-generated catch blocke. printstacktrace () ;}} private void drawview () {// todo auto-generated method stubtry {If (Sh! = NULL) {canvas = Sh. lockcanvas (); // anti-sawtooth canvas. setdrawfilter (New paintflagsdrawfilter (0, paint. anti_alias_flag | paint. filter_bitmap_flag); canvas. drawbitmap (bitmap, 0, 0, null); // do not fill the paint. setstyle (style. stroke); // canvas. drawpath (path, paint); paint. setcolor (color. blue); paint. setstrokewidth (2); canvas. drawrect (rect, paint); paint. setstyle (paint. style. fill); paint. setcolor (color. gree N); // paint. setstrokewidth (3); canvas. drawcircle (rect. left, rect. top, rad, paint); // specifies the painting point. The parameter is a horizontal X axis, the parameter is a vertical Y axis, and the third parameter is a paint object. Canvas. drawcircle (rect. left, (rect. top + rect. bottom)/2, rad, paint); canvas. drawcircle (rect. left, rect. bottom, rad, paint); canvas. drawcircle (rect. left + rect. right)/2, rect. top, rad, paint); canvas. drawcircle (rect. left + rect. right)/2, rect. bottom, rad, paint); canvas. drawcircle (rect. right, rect. top, rad, paint); canvas. drawcircle (rect. right, (rect. top + rect. bottom)/2, RA D, paint); canvas. drawcircle (rect. right, rect. bottom, rad, paint) ;}} catch (exception e) {e. printstacktrace ();} finally {If (canvas! = NULL) Sh. unlockcanvasandpost (canvas) ;}@ override public Boolean onkeydown (INT keycode, keyevent event) {If (keycode = keyevent. keycode_back) {isrunning = false;} return Super. onkeydown (keycode, event );}}

After testing, there are no major bugs, and the demo source code is attached.

Http://download.csdn.net/detail/tianmi1988/4859217

There will inevitably be omissions. You are welcome to correct them and make progress together!

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.