canvas - Android drawing on bitmap is disappear after touch up event -
i trying implement application image device , add canvas start drawing on using brush , eraser (like snapchat idea) used drawing app base
http://code.tutsplus.com/series/create-a-drawing-app-on-android--cms-704
my problem when draw on bitmap start drawing when finished , touch drawing disappear.
this video problem
https://vid.me/rgnf (try mute sound there noise :) )
any appreciated. thank you
public class drawingview extends view { //drawing path private path drawpath; //drawing , canvas paint private paint drawpaint, canvaspaint; //initial color private int paintcolor = 0xff660000; //canvas private canvas drawcanvas; //canvas bitmap public bitmap canvasbitmap; //brush sizes private float brushsize, lastbrushsize; //erase flag private boolean erase=false; public drawingview(context context, attributeset attrs){ super(context, attrs); setupdrawing(); } //setup drawing private void setupdrawing(){ //prepare drawing , setup paint stroke properties brushsize = getresources().getinteger(r.integer.medium_size); lastbrushsize = brushsize; drawpath = new path(); drawpaint = new paint(); drawpaint.setcolor(paintcolor); drawpaint.setantialias(true); drawpaint.setstrokewidth(brushsize); drawpaint.setstyle(paint.style.stroke); drawpaint.setstrokejoin(paint.join.round); drawpaint.setstrokecap(paint.cap.round); canvaspaint = new paint(paint.dither_flag); } //size assigned view @override protected void onsizechanged(int w, int h, int oldw, int oldh) { super.onsizechanged(w, h, oldw, oldh); canvasbitmap = bitmap.createbitmap(w, h, bitmap.config.argb_8888); drawcanvas = new canvas(canvasbitmap); } //draw view - called after touch event @override protected void ondraw(canvas canvas) { super.ondraw(canvas); canvas.drawbitmap(canvasbitmap, 0, 0, canvaspaint); canvas.drawpath(drawpath, drawpaint); } @override public boolean ontouchevent(motionevent event) { float touchx = event.getx(); float touchy = event.gety(); //respond down, move , events switch (event.getaction()) { case motionevent.action_down: drawpath.moveto(touchx, touchy); break; case motionevent.action_move: drawpath.lineto(touchx, touchy); break; case motionevent.action_up: drawpath.lineto(touchx, touchy); drawcanvas.drawpath(drawpath, drawpaint); drawpath.reset(); break; default: return false; } //redraw invalidate(); return true; } //update color public void setcolor(string newcolor){ invalidate(); paintcolor = color.parsecolor(newcolor); drawpaint.setcolor(paintcolor); } //set brush size public void setbrushsize(float newsize){ float pixelamount = typedvalue.applydimension(typedvalue.complex_unit_dip, newsize, getresources().getdisplaymetrics()); brushsize=pixelamount; drawpaint.setstrokewidth(brushsize); } //get , set last brush size public void setlastbrushsize(float lastsize){ lastbrushsize=lastsize; } public float getlastbrushsize(){ return lastbrushsize; } //set erase true or false public void seterase(boolean iserase){ erase=iserase; if(erase) drawpaint.setxfermode(new porterduffxfermode(porterduff.mode.clear)); else drawpaint.setxfermode(null); } //start new drawing public void startnew(){ drawcanvas.drawcolor(0, porterduff.mode.clear); invalidate(); }
}
public class mainactivity extends activity implements onclicklistener { //custom drawing view private drawingview drawview; //buttons private imagebutton currpaint, drawbtn, erasebtn, newbtn, savebtn; //sizes private float smallbrush, mediumbrush, largebrush; button mbtnpick; int mwidth; int mheight; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); mwidth = mheight = 0; //get drawing view drawview = (drawingview)findviewbyid(r.id.drawing); //get palette , first color button linearlayout paintlayout = (linearlayout)findviewbyid(r.id.paint_colors); currpaint = (imagebutton)paintlayout.getchildat(0); currpaint.setimagedrawable(getresources().getdrawable(r.drawable.paint_pressed)); //sizes dimensions smallbrush = getresources().getinteger(r.integer.small_size); mediumbrush = getresources().getinteger(r.integer.medium_size); largebrush = getresources().getinteger(r.integer.large_size); //draw button drawbtn = (imagebutton)findviewbyid(r.id.draw_btn); drawbtn.setonclicklistener(this); //set initial size drawview.setbrushsize(mediumbrush); //erase button erasebtn = (imagebutton)findviewbyid(r.id.erase_btn); erasebtn.setonclicklistener(this); //new button newbtn = (imagebutton)findviewbyid(r.id.new_btn); newbtn.setonclicklistener(this); //save button savebtn = (imagebutton)findviewbyid(r.id.save_btn); savebtn.setonclicklistener(this); // getting reference button "pick image" mbtnpick = (button) findviewbyid(r.id.button); // setting onclicklistener button mbtnpick.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { intent = new intent(); i.settype("image/*"); i.setaction(intent.action_get_content); intent customchooserintent = intent.createchooser(i, "pick image"); startactivityforresult(customchooserintent, 10); } }); if(savedinstancestate!=null){ mwidth = savedinstancestate.getint("width"); mheight = savedinstancestate.getint("height"); bitmap bitmap = savedinstancestate.getparcelable("bitmap"); if(bitmap!=null){ drawview.canvasbitmap=bitmap; } } } @override public boolean oncreateoptionsmenu(menu menu) { // inflate menu; adds items action bar if present. getmenuinflater().inflate(r.menu.menu_main, menu); return true; } //user clicked paint public void paintclicked(view view){ //use chosen color //set erase false drawview.seterase(false); drawview.setbrushsize(drawview.getlastbrushsize()); if(view!=currpaint){ imagebutton imgview = (imagebutton)view; string color = view.gettag().tostring(); drawview.setcolor(color); //update ui imgview.setimagedrawable(getresources().getdrawable(r.drawable.paint_pressed)); currpaint.setimagedrawable(getresources().getdrawable(r.drawable.paint)); currpaint=(imagebutton)view; } } @override public void onclick(view view){ if(view.getid()==r.id.draw_btn){ //draw button clicked final dialog brushdialog = new dialog(this); brushdialog.settitle("brush size:"); brushdialog.setcontentview(r.layout.brush_chooser); //listen clicks on size buttons imagebutton smallbtn = (imagebutton)brushdialog.findviewbyid(r.id.small_brush); smallbtn.setonclicklistener(new onclicklistener(){ @override public void onclick(view v) { drawview.seterase(false); drawview.setbrushsize(smallbrush); drawview.setlastbrushsize(smallbrush); brushdialog.dismiss(); } }); imagebutton mediumbtn = (imagebutton)brushdialog.findviewbyid(r.id.medium_brush); mediumbtn.setonclicklistener(new onclicklistener(){ @override public void onclick(view v) { drawview.seterase(false); drawview.setbrushsize(mediumbrush); drawview.setlastbrushsize(mediumbrush); brushdialog.dismiss(); } }); imagebutton largebtn = (imagebutton)brushdialog.findviewbyid(r.id.large_brush); largebtn.setonclicklistener(new onclicklistener(){ @override public void onclick(view v) { drawview.seterase(false); drawview.setbrushsize(largebrush); drawview.setlastbrushsize(largebrush); brushdialog.dismiss(); } }); //show , wait user interaction brushdialog.show(); } else if(view.getid()==r.id.erase_btn){ //switch erase - choose size final dialog brushdialog = new dialog(this); brushdialog.settitle("eraser size:"); brushdialog.setcontentview(r.layout.brush_chooser); //size buttons imagebutton smallbtn = (imagebutton)brushdialog.findviewbyid(r.id.small_brush); smallbtn.setonclicklistener(new onclicklistener(){ @override public void onclick(view v) { drawview.seterase(true); drawview.setbrushsize(smallbrush); brushdialog.dismiss(); } }); imagebutton mediumbtn = (imagebutton)brushdialog.findviewbyid(r.id.medium_brush); mediumbtn.setonclicklistener(new onclicklistener(){ @override public void onclick(view v) { drawview.seterase(true); drawview.setbrushsize(mediumbrush); brushdialog.dismiss(); } }); imagebutton largebtn = (imagebutton)brushdialog.findviewbyid(r.id.large_brush); largebtn.setonclicklistener(new onclicklistener(){ @override public void onclick(view v) { drawview.seterase(true); drawview.setbrushsize(largebrush); brushdialog.dismiss(); } }); brushdialog.show(); } else if(view.getid()==r.id.new_btn){ //new button alertdialog.builder newdialog = new alertdialog.builder(this); newdialog.settitle("new drawing"); newdialog.setmessage("start new drawing (you lose current drawing)?"); newdialog.setpositivebutton("yes", new dialoginterface.onclicklistener(){ public void onclick(dialoginterface dialog, int which){ drawview.startnew(); dialog.dismiss(); } }); newdialog.setnegativebutton("cancel", new dialoginterface.onclicklistener(){ public void onclick(dialoginterface dialog, int which){ dialog.cancel(); } }); newdialog.show(); } else if(view.getid()==r.id.save_btn){ //save drawing alertdialog.builder savedialog = new alertdialog.builder(this); savedialog.settitle("save drawing"); savedialog.setmessage("save drawing device gallery?"); savedialog.setpositivebutton("yes", new dialoginterface.onclicklistener(){ public void onclick(dialoginterface dialog, int which){ //save drawing drawview.setdrawingcacheenabled(true); //attempt save string imgsaved = mediastore.images.media.insertimage( getcontentresolver(), drawview.getdrawingcache(), uuid.randomuuid().tostring()+".png", "drawing"); //feedback if(imgsaved!=null){ toast savedtoast = toast.maketext(getapplicationcontext(), "drawing saved gallery!", toast.length_short); savedtoast.show(); } else{ toast unsavedtoast = toast.maketext(getapplicationcontext(), "oops! image not saved.", toast.length_short); unsavedtoast.show(); } drawview.destroydrawingcache(); } }); savedialog.setnegativebutton("cancel", new dialoginterface.onclicklistener(){ public void onclick(dialoginterface dialog, int which){ dialog.cancel(); } }); savedialog.show(); } } // courtesy : developer.android.com/training/displaying-bitmaps/load-bitmap.html public static int calculateinsamplesize( bitmapfactory.options options, int reqwidth, int reqheight) { // raw height , width of image final int height = options.outheight; final int width = options.outwidth; int insamplesize = 1; if (height > reqheight || width > reqwidth) { // calculate ratios of height , width requested height , width final int heightratio = math.round((float) height / (float) reqheight); final int widthratio = math.round((float) width / (float) reqwidth); // choose smallest ratio insamplesize value, guarantee // final image both dimensions larger or equal // requested height , width. insamplesize = heightratio < widthratio ? heightratio : widthratio; } return insamplesize; } private bitmap getbitmapfromuri(uri data){ bitmap bitmap = null; // starting fetch image file inputstream is=null; try { = getcontentresolver().openinputstream(data); // first decode injustdecodebounds=true check dimensions final bitmapfactory.options options = new bitmapfactory.options(); options.injustdecodebounds = true; // bitmapfactory.decodefile(path, options); bitmapfactory.decodestream(is, null, options); // calculate insamplesize options.insamplesize = calculateinsamplesize(options, mwidth, mheight); // decode bitmap insamplesize set options.injustdecodebounds = false; = getcontentresolver().openinputstream(data); bitmap = bitmapfactory.decodestream(is,null,options); if(bitmap==null){ toast.maketext(getbasecontext(), "image not loaded",toast.length_short).show(); return null; } is.close(); }catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); }catch(nullpointerexception e){ e.printstacktrace(); } return bitmap; } @override protected void onactivityresult(int requestcode, int resultcode, intent intent) { // todo auto-generated method stub super.onactivityresult(requestcode, resultcode, intent); if (requestcode == 10 && resultcode == result_ok && null != intent) { uri data = intent.getdata(); bitmap bitmap = getbitmapfromuri(data); if(bitmap!=null){ drawview.canvasbitmap=bitmap; } } } @override public void onwindowfocuschanged(boolean hasfocus) { // todo auto-generated method stub super.onwindowfocuschanged(hasfocus); mwidth = drawview.getwidth(); mheight = drawview.getheight(); } @override protected void onsaveinstancestate(bundle outstate) { outstate.putint("width", mwidth); outstate.putint("height", mheight); if(drawview.canvasbitmap!=null){ outstate.putparcelable("bitmap", drawview.canvasbitmap); } super.onsaveinstancestate(outstate); }
}
what doing getting canvas of image via drawcanvas
object , drawing on canvas , drawing path on it.
try way, canvas of image via drawcanvas
object , draw path on , draw resultant image on canvas. see following code
// draw path on canvasbitmap drawcanvas.drawpath(drawpath, drawpaint); //now draw canvasbitmap on canvas canvas.drawbitmap(canvasbitmap, 0, 0, canvaspaint); //canvas.drawpath(drawpath, drawpaint); // no need line
what happening draw path on canvas on action_up , reset path object, see following code of yours
case motionevent.action_up: drawpath.lineto(touchx, touchy); drawcanvas.drawpath(drawpath, drawpaint); drawpath.reset();
according android reset() follows:
clear lines , curves path, making empty.
after above code call invalidate();
clears canvas , redraw empty path object because have called drawpath.reset()
. main reason why lines disappearing.
Comments
Post a Comment