java - Android: Double-Tap zooms out bitmap image when it's not supposed to...? -


i'm building app generate circles on bitmap when user double taps screen. when user pinches in or pinches out, image zooms in , zooms out, , when use 1 finger image can dragged around.

i wrote code draw circle on bitmap when user double-taps, , works except image gets zoomed way out after draws circle...is wrong gesturedetector class wrote (the class @ bottom of following code:)

public class zoominzoomout extends imageview { private static final string tag = "zoomableimageview";  private bitmap imgbitmap = null;  private int containerwidth; private int containerheight;  paint background;  //matrices used move , zoom image matrix matrix = new matrix(); matrix savedmatrix = new matrix();  pointf start = new pointf();  float currentscale; float curx; float cury;  //we can in 1 of these 3 states static final int none = 0; static final int drag = 1; static final int zoom = 2; int mode = none;  //for animating stuff float targetx; float targety; float targetscale; float targetscalex; float targetscaley; float scalechange; float targetratio; float transitionalratio;  float easing = 0.2f; boolean isanimating = false;  float scaledampingfactor = 0.5f;  //for pinch , zoom float olddist = 1f; pointf mid = new pointf();  private handler mhandler = new handler();  float minscale; float maxscale = 8.0f;  float wpradius = 25.0f; float wpinnerradius = 20.0f;  float screendensity; context context; private gesturedetector gesturedetector;  public static final int default_scale_fit_inside = 0; public static final int default_scale_original = 1;  private int defaultscale;  public int getdefaultscale() {     return defaultscale; }  public void setdefaultscale(int defaultscale) {     this.defaultscale = defaultscale; }  public zoominzoomout(context context) {     super(context);     setfocusable(true);     setfocusableintouchmode(true);      screendensity = context.getresources().getdisplaymetrics().density;      initpaints();     gesturedetector = new gesturedetector(new mygesturedetector());     this.context=context; }  public zoominzoomout(context context, attributeset attrs) {     super(context, attrs);      screendensity = context.getresources().getdisplaymetrics().density;     initpaints();     gesturedetector = new gesturedetector(new mygesturedetector());      defaultscale = zoominzoomout.default_scale_fit_inside; }  private void initpaints() {     background = new paint(); }  @override protected void onsizechanged(int width, int height, int oldwidth, int oldheight) {     super.onsizechanged(width, height, oldwidth, oldheight);      //reset width , height. draw bitmap , change     containerwidth = width;     containerheight = height;      if(imgbitmap != null) {         int imgheight = imgbitmap.getheight();         int imgwidth = imgbitmap.getwidth();          float scale;         int initx = 0;         int inity = 0;          if(defaultscale == zoominzoomout.default_scale_fit_inside) {             if(imgwidth > containerwidth) {                 scale = (float)containerwidth / imgwidth;                 float newheight = imgheight * scale;                 inity = (containerheight - (int)newheight)/2;                  matrix.setscale(scale, scale);                 matrix.posttranslate(0, inity);             }             else {                 scale = (float)containerheight / imgheight;                 float newwidth = imgwidth * scale;                 initx = (containerwidth - (int)newwidth)/2;                  matrix.setscale(scale, scale);                 matrix.posttranslate(initx, 0);             }              curx = initx;             cury = inity;              currentscale = scale;             minscale = scale;         }         else {             if(imgwidth > containerwidth) {                 inity = (containerheight - (int)imgheight)/2;                 matrix.posttranslate(0, inity);             }             else {                 initx = (containerwidth - (int)imgwidth)/2;                 matrix.posttranslate(initx, 0);             }              curx = initx;             cury = inity;              currentscale = 1.0f;             minscale = 1.0f;         }           invalidate();     } }  @override protected void ondraw(canvas canvas) {     if(imgbitmap != null && canvas != null)     {         canvas.drawbitmap(imgbitmap, matrix, background);     } }  //checks , sets target image x , y co-ordinates if out of bounds private void checkimageconstraints() {     if(imgbitmap == null) {         return;     }      float[] mvals = new float[9];     matrix.getvalues(mvals);      currentscale = mvals[0];      if(currentscale < minscale) {         float deltascale = minscale / currentscale;         float px = containerwidth/2;         float py = containerheight/2;         matrix.postscale(deltascale, deltascale, px, py);         invalidate();     }      matrix.getvalues(mvals);     currentscale = mvals[0];     curx = mvals[2];     cury = mvals[5];      int rangelimitx = containerwidth - (int)(imgbitmap.getwidth() * currentscale);     int rangelimity = containerheight - (int)(imgbitmap.getheight() * currentscale);       boolean tomovex = false;     boolean tomovey = false;      if(rangelimitx < 0) {         if(curx > 0) {             targetx = 0;             tomovex = true;         }         else if(curx < rangelimitx) {             targetx = rangelimitx;             tomovex = true;         }     }     else {         targetx = rangelimitx / 2;         tomovex = true;     }      if(rangelimity < 0) {         if(cury > 0) {             targety = 0;             tomovey = true;         }         else if(cury < rangelimity) {             targety = rangelimity;             tomovey = true;         }     }     else {         targety = rangelimity / 2;         tomovey = true;     }      if(tomovex == true || tomovey == true) {         if(tomovey == false) {             targety = cury;         }         if(tomovex == false) {             targetx = curx;         }          //disable touch event actions         isanimating = true;         //initialize timer         mhandler.removecallbacks(mupdateimagepositiontask);         mhandler.postdelayed(mupdateimagepositiontask, 100);     } }   @override public boolean ontouchevent(motionevent event) {     float oldx = 0, newx = 0, sens = 5;     if(gesturedetector.ontouchevent(event)) {         return true;     }      if(isanimating == true) {         return true;     }      //handle touch events here     float[] mvals = new float[9];     switch(event.getaction() & motionevent.action_mask) {         case motionevent.action_down:             if(isanimating == false) {                 savedmatrix.set(matrix);                 oldx = event.getx();                 start.set(event.getx(), event.gety());                 mode = drag;             }             break;          case motionevent.action_pointer_down:             olddist = spacing(event);             if(olddist > 10f) {                 savedmatrix.set(matrix);                 midpoint(mid, event);                 mode = zoom;             }             break;         case motionevent.action_up:             newx = event.getx();             if (math.abs(oldx - newx) < sens) {                 toast.maketext(context, "hello", toast.length_long).show();                 return true;             }             oldx = 0;             newx = 0;             break;         case motionevent.action_pointer_up:             mode = none;              matrix.getvalues(mvals);             curx = mvals[2];             cury = mvals[5];             currentscale = mvals[0];              if(isanimating == false) {                 checkimageconstraints();             }             break;          case motionevent.action_move:             if(mode == drag && isanimating == false) {                 matrix.set(savedmatrix);                 float diffx = event.getx() - start.x;                 float diffy = event.gety() - start.y;                  matrix.posttranslate(diffx, diffy);                  matrix.getvalues(mvals);                 curx = mvals[2];                 cury = mvals[5];                 currentscale = mvals[0];             }             else if(mode == zoom && isanimating == false) {                 float newdist = spacing(event);                 if(newdist > 10f) {                     matrix.set(savedmatrix);                     float scale = newdist / olddist;                     matrix.getvalues(mvals);                     currentscale = mvals[0];                      if(currentscale * scale <= minscale) {                         matrix.postscale(minscale/currentscale, minscale/currentscale, mid.x, mid.y);                     }                     else if(currentscale * scale >= maxscale) {                         matrix.postscale(maxscale/currentscale, maxscale/currentscale, mid.x, mid.y);                     }                     else {                         matrix.postscale(scale, scale, mid.x, mid.y);                     }                       matrix.getvalues(mvals);                     curx = mvals[2];                     cury = mvals[5];                     currentscale = mvals[0];                 }             }              break;     }      //calculate transformations , invalidate     invalidate();     return true; }  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); }  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 void setimagebitmap(bitmap b) {     if(b != null) {         imgbitmap = b;          containerwidth = getwidth();         containerheight = getheight();          int imgheight = imgbitmap.getheight();         int imgwidth = imgbitmap.getwidth();          float scale;         int initx = 0;         int inity = 0;          matrix.reset();          if(defaultscale == zoominzoomout.default_scale_fit_inside) {             if(imgwidth > containerwidth) {                 scale = (float)containerwidth / imgwidth;                 float newheight = imgheight * scale;                 inity = (containerheight - (int)newheight)/2;                  matrix.setscale(scale, scale);                 matrix.posttranslate(0, inity);             }             else {                 scale = (float)containerheight / imgheight;                 float newwidth = imgwidth * scale;                 initx = (containerwidth - (int)newwidth)/2;                  matrix.setscale(scale, scale);                 matrix.posttranslate(initx, 0);             }              curx = initx;             cury = inity;              currentscale = scale;             minscale = scale;         }         else {             if(imgwidth > containerwidth) {                 initx = 0;                 if(imgheight > containerheight) {                     inity = 0;                 }                 else {                     inity = (containerheight - (int)imgheight)/2;                 }                  matrix.posttranslate(0, inity);             }             else {                 initx = (containerwidth - (int)imgwidth)/2;                 if(imgheight > containerheight) {                     inity = 0;                 }                 else {                     inity = (containerheight - (int)imgheight)/2;                 }                 matrix.posttranslate(initx, 0);             }              curx = initx;             cury = inity;              currentscale = 1.0f;             minscale = 1.0f;         }          invalidate();     }     else {         log.d(tag, "bitmap null");     } }  public bitmap getphotobitmap() {     return imgbitmap; }   private runnable mupdateimagepositiontask = new runnable() {     public void run() {         float[] mvals;          if(math.abs(targetx - curx) < 5 && math.abs(targety - cury) < 5) {             isanimating = false;             mhandler.removecallbacks(mupdateimagepositiontask);              mvals = new float[9];             matrix.getvalues(mvals);              currentscale = mvals[0];             curx = mvals[2];             cury = mvals[5];              //set image parameters , invalidate display             float diffx = (targetx - curx);             float diffy = (targety - cury);              matrix.posttranslate(diffx, diffy);         }         else {             isanimating = true;             mvals = new float[9];             matrix.getvalues(mvals);              currentscale = mvals[0];             curx = mvals[2];             cury = mvals[5];              //set image parameters , invalidate display             float diffx = (targetx - curx) * 0.3f;             float diffy = (targety - cury) * 0.3f;              matrix.posttranslate(diffx, diffy);             mhandler.postdelayed(this, 25);         }          invalidate();     } };  private runnable mupdateimagescale = new runnable() {     public void run() {         float transitionalratio = targetscale / currentscale;         float dx;         if(math.abs(transitionalratio - 1) > 0.05) {             isanimating = true;             if(targetscale > currentscale) {                 dx = transitionalratio - 1;                 scalechange = 1 + dx * 0.2f;                  currentscale *= scalechange;                  if(currentscale > targetscale) {                     currentscale = currentscale / scalechange;                     scalechange = 1;                 }             }             else {                 dx = 1 - transitionalratio;                 scalechange = 1 - dx * 0.5f;                 currentscale *= scalechange;                  if(currentscale < targetscale) {                     currentscale = currentscale / scalechange;                     scalechange = 1;                 }             }               if(scalechange != 1) {                 matrix.postscale(scalechange, scalechange, targetscalex, targetscaley);                 mhandler.postdelayed(mupdateimagescale, 15);                 invalidate();             }             else {                 isanimating = false;                 scalechange = 1;                 matrix.postscale(targetscale/currentscale, targetscale/currentscale, targetscalex, targetscaley);                 currentscale = targetscale;                 mhandler.removecallbacks(mupdateimagescale);                 invalidate();                 checkimageconstraints();             }         }         else {             isanimating = false;             scalechange = 1;             matrix.postscale(targetscale/currentscale, targetscale/currentscale, targetscalex, targetscaley);             currentscale = targetscale;             mhandler.removecallbacks(mupdateimagescale);             invalidate();             checkimageconstraints();         }     } };  /** show event in logcat view, debugging */ private void dumpevent(motionevent event) {     string names[] = { "down", "up", "move", "cancel", "outside", "pointer_down", "pointer_up", "7?", "8?", "9?" };     stringbuilder sb = new stringbuilder();     int action = event.getaction();     int actioncode = action & motionevent.action_mask;     sb.append("event action_").append(names[actioncode]);     if (actioncode == motionevent.action_pointer_down || actioncode == motionevent.action_pointer_up) {         sb.append("(pid ").append(action >> motionevent.action_pointer_id_shift);         sb.append(")");     }     sb.append("[");      (int = 0; < event.getpointercount(); i++) {         sb.append("#").append(i);         sb.append("(pid ").append(event.getpointerid(i));         sb.append(")=").append((int) event.getx(i));         sb.append(",").append((int) event.gety(i));         if (i + 1 < event.getpointercount())             sb.append(";");     }     sb.append("]"); }  class mygesturedetector extends simpleongesturelistener {        @override     public boolean ondoubletap(motionevent event) {           bitmap bmoverlay = bitmap.createbitmap(imgbitmap.getwidth(),                imgbitmap.getheight(),                 imgbitmap.getconfig());         canvas canvas = new canvas(bmoverlay);         paint p = new paint();         p.setantialias(true);         p.setcolor(color.red);         p.setstrokewidth(2);         p.setstyle(paint.style.stroke);         canvas.drawbitmap(imgbitmap, matrix, null);         canvas.drawcircle((int)event.getx(),(int)event.gety(),                 100, p);          setimagebitmap(bmoverlay);         return true;     }       @override     public boolean ondown(motionevent e) {         return false;     } } 

}

you're setting image bitmap. setimagebitmap call matrix.reset. when that, you're losing zoom factor. need fiddle code/architecture prevent call.


Comments

Popular posts from this blog

c++ - Delete matches in OpenCV (Keypoints and descriptors) -

java - Could not locate OpenAL library -

sorting - opencl Bitonic sort with 64 bits keys -