canvas - Absolute position click potion of zoomed image in android -


i want calculate un-scaled absolute position of image drawn on canvas based on position clicked user on scaled canvas.

i used following zoom implementation translate/scale bitmap within boundaries?

so far,

public boolean inme(int x, int y, region clickregion) {     if(mscalefactor == 0)                  mscalefactor = 1;              float curx = ((x*1.0f)/ mscalefactor) - (mposx * mscalefactor);             float cury = ((y*1.0f) / mscalefactor) - (mposy * mscalefactor);              x = (int)curx;             y = (int)cury;              //clickregion grapics.region computed on non-zoomed coordinates             if (clickregion.contains(x, y))                 return true;             else                 return false; } 

this works fine, when there no zooming, when zoomed there significant issues.

edit

this algo used zooming , panning.

    public class panzoomview extends view {      public static final string tag = panzoomview.class.getname();      private static final int invalid_pointer_id = -1;      // ‘active pointer’ 1 moving our object.     private int mactivepointerid = invalid_pointer_id;      private bitmap bitmap;     private float viewheight;     private float viewwidth;     float canvaswidth, canvasheight;      private scalegesturedetector mscaledetector;     private float mscalefactor = 1.f;     private float minscalefactor;      private float mposx;     private float mposy;      private float mlasttouchx, mlasttouchy;      private boolean firstdraw = true;      private boolean panenabled = true;     private boolean zoomenabled = true;      public panzoomview(context context) {         super(context);         setup();     }      public panzoomview(context context, attributeset attrs, int defstyle) {         super(context, attrs, defstyle);         setup();     }      public panzoomview(context context, attributeset attrs) {         super(context, attrs);         setup();     }      private void setup() {         mscaledetector = new scalegesturedetector(getcontext(), new scalelistener());     }      public void setbitmap(bitmap bmp) {         setimagebitmap(bmp);     }      public void setimagebitmap(bitmap bmp) {         bitmap = bmp;         resetzoom();         resetpan();         firstdraw = true;         invalidate();     }      public bitmap getimagebitmap() {         return bitmap;     }      public bitmap getbitmap() {         return getimagebitmap();     }      public void resetzoom() {         mscalefactor = 1.0f;     }      public void resetpan() {         mposx = 0f;         mposy = 0f;     }      public void setimagedrawable(drawable drawable) {         setimagebitmap(((bitmapdrawable) drawable).getbitmap());     }      public bitmapdrawable getimagedrawable() {         bitmapdrawable bd = new bitmapdrawable(getcontext().getresources(), bitmap);         return bd;     }      public bitmapdrawable getdrawable() {         return getimagedrawable();     }      public void ondraw(canvas canvas) { //      log.v(tag, "ondraw()");          if (bitmap == null) {             log.w(tag, "nothing draw - bitmap null");             super.ondraw(canvas);             return;         }          if (firstdraw                  && (bitmap.getheight() > 0)                  && (bitmap.getwidth() > 0)) {             //don't let user zoom out image smaller             //than containing frame             float minxscalefactor = (float) viewwidth / (float) bitmap.getwidth();             float minyscalefactor = (float) viewheight / (float) bitmap.getheight();             minscalefactor = math.max(minxscalefactor, minyscalefactor);             log.d(tag, "minscalefactor: " + minscalefactor);             mscalefactor = minscalefactor; //start out "zoomed out" way              mposx = mposy = 0;             firstdraw = false;          }         mscalefactor = math.max(mscalefactor, minscalefactor);          canvasheight = canvas.getheight();         canvaswidth = canvas.getwidth(); //      log.d(tag, "canvas density: " + canvas.getdensity() + " bitmap density: " + bitmap.getdensity());  //      log.d(tag, "mscalefactor: " + mscalefactor);          //save canvas without translating (panning) or scaling (zooming)         //after each change, restore state, instead of compounding         //changes upon changes         canvas.save();         int maxx, minx, maxy, miny;         //regardless of screen density (hdpi, mdpi) or scale factor,          //the image consists of bitmap width divided 2 pixels. if image         //is 200 pixels wide , scroll right 100 pixels, scrolled image         //off screen left.         minx = (int) (((viewwidth / mscalefactor) - bitmap.getwidth()) / 2);         maxx = 0;         //how far can move image vertically without having gap between image , frame?         miny = (int) (((viewheight / mscalefactor) - bitmap.getheight()) / 2);         maxy = 0;         log.d(tag, "minx: " + minx + " maxx: " + maxx + " miny: " + miny + " maxy: " + maxy);         //do not go beyond boundaries of image         if (mposx > maxx) {             mposx = maxx;         }         if (mposx < minx) {             mposx = minx;         }         if (mposy > maxy) {             mposy = maxy;         }         if (mposy < miny) {             mposy = miny;         }  //      log.d(tag, "view width: " + viewwidth + " view height: " //              + viewheight); //      log.d(tag, "bitmap width: " + bitmap.getwidth() + " height: " + bitmap.getheight()); //      log.d(tag, "translating mposx: " + mposx + " mposy: " + mposy);  //      log.d(tag, "zooming scale factor of " + mscalefactor);         canvas.scale(mscalefactor, mscalefactor);  //      log.d(tag, "panning " + mposx + "," + mposy);          canvas.translate(mposx, mposy);          super.ondraw(canvas);         canvas.drawbitmap(bitmap, mposx, mposy, null);         canvas.restore(); //clear translation/scaling     }      @override     public boolean ontouchevent(motionevent ev) {         // let scalegesturedetector inspect events.         if (zoomenabled) {             mscaledetector.ontouchevent(ev);         }          if (panenabled) {             final int action = ev.getaction();             switch (action & motionevent.action_mask) {                 case motionevent.action_down: {                     final float x = ev.getx();                     final float y = ev.gety();                      mlasttouchx = x;                     mlasttouchy = y;                     mactivepointerid = ev.getpointerid(0);                     break;                 }                  case motionevent.action_move: {                     final int pointerindex = ev.findpointerindex(mactivepointerid);                     final float x = ev.getx(pointerindex);                     final float y = ev.gety(pointerindex);                      // move if scalegesturedetector isn't processing gesture.                     if (!mscaledetector.isinprogress()) {                         float dx = x - mlasttouchx;                         float dy = y - mlasttouchy;                          //adjust zoom factor. otherwise, user's finger moving 10 pixels                         //at 200% zoom causes image slide 20 pixels instead of                         //following user's touch                         dx /= (mscalefactor * 2);                         dy /= (mscalefactor * 2);                          mposx += dx;                         mposy += dy;                          log.v(tag, "moving " + dx + "," + dy + " mscalefactor: " + mscalefactor);                          invalidate();                     }                      mlasttouchx = x;                     mlasttouchy = y;                      break;                 }                  case motionevent.action_up: {                     mactivepointerid = invalid_pointer_id;                     break;                 }                  case motionevent.action_cancel: {                     mactivepointerid = invalid_pointer_id;                     break;                 }                  case motionevent.action_pointer_up: {                     final int pointerindex = (ev.getaction() & motionevent.action_pointer_index_mask) >> motionevent.action_pointer_index_shift;                     final int pointerid = ev.getpointerid(pointerindex);                     if (pointerid == mactivepointerid) {                         // our active pointer going up. choose new                         // active pointer , adjust accordingly.                         final int newpointerindex = pointerindex == 0 ? 1 : 0;                         mlasttouchx = ev.getx(newpointerindex);                         mlasttouchy = ev.gety(newpointerindex);                         mactivepointerid = ev.getpointerid(newpointerindex);                     }                     break;                 }             }         }         return true;     }      private class scalelistener extends             scalegesturedetector.simpleonscalegesturelistener {         @override         public boolean onscale(scalegesturedetector detector) {             mscalefactor *= detector.getscalefactor();             // don't let object small or large.             mscalefactor = math.max(0.1f, math.min(mscalefactor, 5.0f)); //          log.d(tag, "detector scale factor: " + detector.getscalefactor() + " mscalefactor: " + mscalefactor);              invalidate();             return true;         }     }      //currently zoomenabled/panenabled can set programmatically, not in xml      public boolean ispanenabled() {         return panenabled;     }      public void setpanenabled(boolean panenabled) {         this.panenabled = panenabled;     }      public boolean iszoomenabled() {         return zoomenabled;     }      public void setzoomenabled(boolean zoomenabled) {         this.zoomenabled = zoomenabled;     }      /**      * calls getcroppedbitmap(int outputwidth, int outputheight) without      * scaling resulting bitmap specific size.      * @return      */     public bitmap getcroppedbitmap() {         return getcroppedbitmap(0, 0);     }      /**      * takes section of bitmap visible in view object      * , exports bitmap object, taking account both      * translation (panning) , zoom (scaling).      * warning: run in separate thread, not on ui thread!      * if specify 200x200 image should have outputwidth      * of 400 , outputheight of 50, image squished      * , stretched dimensions.      * @param outputwidth desired width of output bitmap in pixels      * @param outputheight desired height of output bitmap in pixels      * @return visible portion of image in panzoomimageview      */     public bitmap getcroppedbitmap(int outputwidth, int outputheight) {         int origx = -1 * (int) mposx * 2;         int origy = -1 * (int) mposy * 2;         int width = (int) (viewwidth / mscalefactor);         int height = (int) (viewheight / mscalefactor);         log.e(tag, "origx: " + origx + " origy: " + origy + " width: " + width + " height: " + height + " outputwidth: " + outputwidth + " outputheight: " + outputheight + "getlayoutparams().width: " + getlayoutparams().width + " getlayoutparams().height: " + getlayoutparams().height);         bitmap b = bitmap.createbitmap(bitmap, origx, origy, width, height);          if (outputwidth > 0 && outputwidth > 0) {             //use exact dimensions given--chance won't match aspect ratio             b = bitmap.createscaledbitmap(b, outputwidth, outputheight, true);         }          return b;     }        @override         protected void onsizechanged(int w, int h, int oldw, int oldh) {             super.onsizechanged(w, h, oldw, oldh);             viewheight = h;             viewwidth = w;         } } 

thanks comment, worked me.

public boolean inme(int x, int y, region clickregion) {       float curx = ((x*1.0f)) + (-1*mposx * 2* mscalefactor);     float cury = ((y*1.0f)) + (-1*mposy * 2* mscalefactor);      x = (int)((curx/ mscalefactor));     y = (int)((cury/ mscalefactor));      if (cluster.clickregion.contains(x, y))         return true;     else         return false; } 

Comments

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -