view with Zoom and draw line on canvas in Android -
i working on canvas.as shown below view class use zoom , draw line.on click of zoom button pinch zoom working fine.but when click on paint button pass 1 boolean true draw line on touch of finger.but after draw line on image want start pinch zoom again drawing line on particular position of image(zoom drawing line + image
)
. want start pinch zoom on image 2 shown in paint image.i have tried search still no success. thanks
public class demoview extends view { private static final float stroke_width = 5f; /** need track dirty region can accommodate stroke. **/ private static final float half_stroke_width = stroke_width / 2; private paint paint = new paint(); private path path = new path(); // these matrices used move , zoom image matrix matrix = new matrix(); matrix savedmatrix = new matrix(); // can in 1 of these 3 states static final int none = 0; static final int drag = 1; static final int zoom = 0; public static float xvalue; public static float yvalue; private static final float max_zoom = 10; int mode = none; // remember things zooming pointf start = new pointf(); pointf mid = new pointf(); float olddist = 1f; private float globalx; private float globaly; private float width; private float height; /** * optimizes painting invalidating smallest possible area. */ private float lasttouchx; private float lasttouchy; private final rectf dirtyrect = new rectf(); private boolean flag; private bitmap bgbitmap; private float mscalefactor; private int mactivepointerid; private float mposx; private float mposy; public demoview(context context, attributeset attrs) { super(context, attrs); paint.setantialias(true); paint.setcolor(color.black); paint.setstyle(paint.style.stroke); paint.setstrokejoin(paint.join.round); paint.setstrokewidth(stroke_width); bgbitmap = bitmapfactory.decoderesource(context.getresources(), r.drawable.nat); } @override public void draw(canvas canvas) { super.draw(canvas); canvas.save(); canvas.translate(mposx, mposy); canvas.scale(mscalefactor, mscalefactor); canvas.drawbitmap(bgbitmap, 0,0,null); if(mscalefactor != 1.f) canvas.restore(); if(flag) canvas.drawpath(path,paint); if(mscalefactor == 1.f) canvas.restore(); } /** * erases signature. */ public void clear() { path.reset(); // repaints entire view. invalidate(); } @override public boolean ontouchevent(motionevent event) { float eventx = event.getx(); float eventy = event.gety(); switch (event.getaction()) { case motionevent.action_down: if (flag) { path.moveto(eventx, eventy); lasttouchx = eventx; lasttouchy = eventy; // there no end point yet, don't waste cycles invalidating. return true; }else{ savedmatrix.set(matrix); start.set(event.getx(), event.gety()); mode = drag; mactivepointerid = event.getpointerid(0); break; } case motionevent.action_pointer_down: olddist = spacing(event); if (olddist > 10f) { savedmatrix.set(matrix); midpoint(mid, event); mode = zoom; } break; case motionevent.action_pointer_up: mode = none; break; case motionevent.action_move: case motionevent.action_up: if (flag) { resetdirtyrect(eventx, eventy); // when hardware tracks events faster delivered, // // event contain history of skipped points. int historysize = event.gethistorysize(); (int = 0; < historysize; i++) { float historicalx = event.gethistoricalx(i); float historicaly = event.gethistoricaly(i); expanddirtyrect(historicalx, historicaly); path.lineto(historicalx, historicaly); } // after replaying history, connect line touch point. path.lineto(eventx, eventy); break; }else{ // start tracking dirty region. if (mode == drag) { // ... matrix.set(savedmatrix); matrix.posttranslate(event.getx() - start.x, event.gety() - start.y); } else if (mode == zoom) { float newdist = spacing(event); if (newdist > 10f) { matrix.set(savedmatrix); float scale = newdist / olddist; matrix.postscale(scale, scale, mid.x, mid.y); } // final int pointerindex = event.findpointerindex((integer) mactivepointerid); // final float x = event.getx(pointerindex); // final float y = event.gety(pointerindex); // // final float dx = x - globalx; // final float dy = y - globaly; // mposx += dx; // mposy += dy; } } default: log.e("ignored touch event: " ,"i"+ event.tostring()); return false; } // include half stroke width avoid clipping. invalidate((int) (dirtyrect.left - half_stroke_width), (int) (dirtyrect.top - half_stroke_width), (int) (dirtyrect.right + half_stroke_width), (int) (dirtyrect.bottom + half_stroke_width)); lasttouchx = eventx; lasttouchy = eventy; return true; } /** * called when replaying history ensure dirty region includes * points. */ private void expanddirtyrect(float historicalx, float historicaly) { if (historicalx < dirtyrect.left) { dirtyrect.left = historicalx; } else if (historicalx > dirtyrect.right) { dirtyrect.right = historicalx; } if (historicaly < dirtyrect.top) { dirtyrect.top = historicaly; } else if (historicaly > dirtyrect.bottom) { dirtyrect.bottom = historicaly; } } /** * resets dirty region when motion event occurs. */ private void resetdirtyrect(float eventx, float eventy) { // lasttouchx , lasttouchy set when action_down // motion event occurred. dirtyrect.left = math.min(lasttouchx, eventx); dirtyrect.right = math.max(lasttouchx, eventx); dirtyrect.top = math.min(lasttouchy, eventy); dirtyrect.bottom = math.max(lasttouchy, eventy); } /** determine space between first 2 fingers */ private float spacing(motionevent event) { float x = event.getx(0) - event.getx(1); float y = event.gety(0) - event.gety(1); return floatmath.sqrt(x * x + y * y); } /** calculate mid point of first 2 fingers */ private void midpoint(pointf point, motionevent event) { float x = event.getx(0) + event.getx(1); float y = event.gety(0) + event.gety(1); point.set(x / 2, y / 2); } public boolean setflag(boolean b) { return flag = b; } }
image pinch zoom , paint on image.
imageview.setontouchlistener(new ontouchlistener() { @override public boolean ontouch(view v, motionevent event) { imageview view = (imageview) v; switch (event.getaction() & motionevent.action_mask) { case motionevent.action_down: savedmatrix.set(matrix1); start.set(event.getx(), event.gety()); mode = drag; break; case motionevent.action_pointer_down: olddist = spacing(event); if (olddist > 10f) { start.set(event.getx(), event.gety()); savedmatrix.set(matrix1); midpoint(mid, event); // mode = point2; mode = zoom; } break; case motionevent.action_up: mode = none; distanceoffset = minoffset; case motionevent.action_pointer_up: mode = none; distanceoffset = minoffset; break; case motionevent.action_move: if (mode == point2) { newdist = spacing(event); if (newdist - olddist > 5f || newdist - olddist < -5f) { mode = zoom; } else { start.set(event.getx(), event.gety()); mode = drag; } } else if (mode == drag) { matrix1.set(savedmatrix); matrix1.posttranslate(event.getx() - start.x, event.gety() - start.y); } else if (mode == zoom) { newdist = spacing(event); if (newdist > 10f) { matrix1.set(savedmatrix); float scale = newdist / olddist; matrix1.postscale(scale, scale, mid.x, mid.y); finalscale = scale; } } break; } view.setimagematrix(matrix1); // matrixturning(matrix1, view); return true; // indicate event handled } }); } mpaintview.setontouchlistener(new ontouchlistener() { @override public boolean ontouch(view v, motionevent event) { paintview view = (paintview) v; view.setscaletype(imageview.scaletype.matrix); switch (event.getaction() & motionevent.action_mask) { case motionevent.action_down: if (falg) { savedmatrix.set(matrix); start.set(event.getx(), event.gety()); mode = drag; } else { view.ontouchevent(event); } break; case motionevent.action_pointer_down: if (falg) { olddist = spacing(event); if (olddist > 10f) { start.set(event.getx(), event.gety()); savedmatrix.set(matrix); midpoint(mid, event); mode = zoom; } } break; case motionevent.action_up: if (falg) { mode = none; distanceoffset = minoffset; } case motionevent.action_pointer_up: if (falg) { mode = none; distanceoffset = minoffset; } break; case motionevent.action_move: if (falg) { if (mode == point2) { newdist = spacing(event); if (newdist - olddist > 5f || newdist - olddist < -5f) { mode = zoom; } else { start.set(event.getx(), event.gety()); mode = drag; } } else if (mode == drag) { matrix.set(savedmatrix); matrix.posttranslate(event.getx() - start.x, event.gety() - start.y); } else if (mode == zoom) { newdist = spacing(event); if (newdist > 10f) { matrix.set(savedmatrix); float scale = newdist / olddist; matrix.postscale(scale, scale, mid.x, mid.y); finalscale = scale; } } } else { view.ontouchevent(event); } break; } limitzoom(matrix); view.setimagematrix(matrix); matrixturning(matrix, view); rectf r = new rectf(); matrix.maprect(r); scaledimageoffsetx = r.left; scaledimageoffsety = r.top; return true; } }); } private void limitzoom(matrix m) { float[] values = new float[9]; m.getvalues(values); float scalex = values[matrix.mscale_x]; float scaley = values[matrix.mscale_y]; if(scalex > max_zoom) { scalex = max_zoom; } else if(scalex < min_zoom) { scalex = min_zoom; } if(scaley > max_zoom) { scaley = max_zoom; } else if(scaley < min_zoom) { scaley = min_zoom; } values[matrix.mscale_x] = scalex; values[matrix.mscale_y] = scaley; m.setvalues(values); } public boolean getflag(boolean b) { return falg = b; } paintview.class
class paintview extends imageview { private bitmap mbitmap; private canvas mcanvas; private path mpath; private paint mbitmappaint; // ondraw private paint mpaint; // ontouch private float mx, my; private static final float touch_tolerance = 4; public paintview(context context) { this(context, null); } public paintview(context context, attributeset attrs) { super(context, attrs); mbitmap = bitmap.createbitmap(1024, 1024, bitmap.config.argb_8888); mpath = new path(); mbitmappaint = new paint(paint.dither_flag); } @override protected void onsizechanged(int w, int h, int oldw, int oldh) { super.onsizechanged(w, h, oldw, oldh); } @override protected void ondraw(canvas canvas) { // canvas.drawcolor(0xffaaaaaa); super.ondraw(canvas); mcanvas = canvas; // canvas = mcanvas; canvas.drawbitmap(mbitmap, 0, 0, mbitmappaint); // canvas.drawbitmap(mbitmap, paintscreen.matrix, mbitmappaint); canvas.drawpath(mpath, mpaint); } public void clear() { mpaint.reset(); // invalidate(); } public void setmpaint(paint paint) { mpaint = paint; } private void touchstart(float x, float y) { // mpath.reset(); mpath.moveto(x, y); mx = x; = y; } private void touchmove(float x, float y) { float dx = math.abs(x - mx); float dy = math.abs(y - my); if (dx >= touch_tolerance || dy >= touch_tolerance) { mpath.quadto(mx, my, (x + mx) / 2, (y + my) / 2); mx = x; = y; } } private void touchup() { mpath.lineto(mx, my); // commit path our offscreen mcanvas.drawpath(mpath, mpaint); // kill don't double draw mpath.reset(); } @override public boolean ontouchevent(motionevent event) { float x = event.getx(); float y = event.gety(); log.d("paintview", "ev ->" + event.getaction()); switch (event.getaction()) { case motionevent.action_down: touchstart(x, y); invalidate(); break; case motionevent.action_move: touchmove(x, y); invalidate(); break; case motionevent.action_up: touchup(); invalidate(); break; } return true; } public void cmatrix(matrix matrix) { mcanvas.setmatrix(matrix); } }
Comments
Post a Comment