2010-09-28 11 views
8

Wie Max und Min Zoomstufen für Pinch-Zoom einstellen?Maßstabsgrenzen für Pinch Zoom von Android


Hier ist mein Code: //

public class TouchImageView extends ImageView { 

    private static final String TAG = "Touch"; 

     // These matrices will be used to move and zoom image 
     Matrix matrix = new Matrix(); 
     Matrix savedMatrix = new Matrix(); 
     static PinchZoomExample sPinchZoomExample = null; 
     // We can be in one of these 3 states 
     static final int NONE = 0; 
     static final int DRAG = 1; 
     static final int ZOOM = 2; 
     int mode = NONE; 
     static Bitmap sCurrentImage; 

     // Remember some things for zooming 
     PointF start = new PointF(); 
     PointF mid = new PointF(); 
     float oldDist = 1f; 

     Context context; 


     public TouchImageView(Context context) { 
      super(context); 
      super.setClickable(true); 
      this.context = context; 

      matrix.setTranslate(1f, 1f); 
      setImageMatrix(matrix); 
      setScaleType(ScaleType.MATRIX); 

      setOnTouchListener(new OnTouchListener() { 

       @Override 
       public boolean onTouch(View v, MotionEvent rawEvent) { 
        WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent); 

        // Dump touch event to log 
        /* if (Viewer.isDebug == true){ 
         dumpEvent(event); 
        }*/ 

        // Handle touch events here... 
        switch (event.getAction() & MotionEvent.ACTION_MASK) { 
        case MotionEvent.ACTION_DOWN: 
         savedMatrix.set(matrix); 
         start.set(event.getX(), event.getY()); 
         Log.d(TAG, "mode=DRAG"); 
         mode = DRAG; 
         break; 
        case MotionEvent.ACTION_POINTER_DOWN: 
         oldDist = spacing(event); 
         Log.d(TAG, "oldDist=" + oldDist); 
         if (oldDist > 10f) { 
          savedMatrix.set(matrix); 
          midPoint(mid, event); 
          mode = ZOOM; 
          Log.d(TAG, "mode=ZOOM"); 
         } 
         break; 
        case MotionEvent.ACTION_UP: 
         int xDiff = (int) Math.abs(event.getX() - start.x); 
         int yDiff = (int) Math.abs(event.getY() - start.y); 
         if (xDiff < 8 && yDiff < 8){ 
          performClick(); 
          sPinchZoomExample.displayGallery(); 
         } 
        case MotionEvent.ACTION_POINTER_UP: 
         mode = NONE; 
         Log.d(TAG, "mode=NONE"); 
         break; 
        case MotionEvent.ACTION_MOVE: 
         if (mode == DRAG) { 
          // ... 
          matrix.set(savedMatrix); 
          matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); 
         } else if (mode == ZOOM) { 
          float newDist = spacing(event); 
          Log.d(TAG, "newDist=" + newDist); 
          if (newDist > 10f) { 
           matrix.set(savedMatrix); 
           float scale = newDist/oldDist; 

           matrix.postScale(scale, scale, mid.x, mid.y); 

           //Canvas canvas = new Canvas(); 

//        Bitmap bm = Bitmap.createBitmap(sCurrentImage,0, 0, sCurrentImage.getWidth() 
//          , sCurrentImage.getHeight(), matrix, true); 
           Log.d("SCALE", "scale=" + scale + " " + getWidth() + " " + getHeight()); 
           //bm.recycle(); 
          } 
         } 
         break; 
        } 

        setImageMatrix(matrix); 
        return true; // indicate event was handled 
       } 

      }); 
     } 


     public void setImage(Bitmap bm, int displayWidth, int displayHeight , PinchZoomExample pze) { 
      super.setImageBitmap(bm); 
      sCurrentImage = bm; 
      sPinchZoomExample = pze; 
      //Fit to screen. 
      float scale; 
      if ((displayHeight/bm.getHeight()) >= (displayWidth/bm.getWidth())){ 
       scale = (float)displayWidth/(float)bm.getWidth(); 
      } else { 
       scale = (float)displayHeight/(float)bm.getHeight(); 
      } 

      savedMatrix.set(matrix); 
      matrix.set(savedMatrix); 
      matrix.postScale(scale, scale, mid.x, mid.y); 
      setImageMatrix(matrix); 


      // Center the image 
      float redundantYSpace = (float)displayHeight - (scale * (float)bm.getHeight()) ; 
      float redundantXSpace = (float)displayWidth - (scale * (float)bm.getWidth()); 

      redundantYSpace /= (float)2; 
      redundantXSpace /= (float)2; 


      savedMatrix.set(matrix); 
      matrix.set(savedMatrix); 
      matrix.postTranslate(redundantXSpace, redundantYSpace); //matrix.postTranslate(50, 50); 
      setImageMatrix(matrix); 


     } 




     /** Determine the space between the first two fingers */ 
     private float spacing(WrapMotionEvent 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 the mid point of the first two fingers */ 
     private void midPoint(PointF point, WrapMotionEvent event) { 
      // ... 
      float x = event.getX(0) + event.getX(1); 
      float y = event.getY(0) + event.getY(1); 
      point.set(x/2, y/2); 
     } 

} 
+0

Es hängt davon ab, wie Sie es implementiert haben. Können wir etwas Code sehen? – fredley

+0

Hier ist mein Code: – Audum

Antwort

6
private static final float MIN_ZOOM = 1.0f; 
private static final float MAX_ZOOM = 5.0f; 

scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM)); 
+2

Downgraded. Dies begrenzt die Skalierung für eine Aktion (Zoom-Geste). Mit mehreren Aktionen konnte der Benutzer über den maximalen oder minimalen Zoom hinaus skalieren. – ALiGOTec

+0

Entschuldigung, ich folge nicht. Können Sie Ihren Kommentar zu mehreren Aktionen und deren Skalierung über den maximalen oder minimalen Zoom hinaus erläutern? –

+0

Bei jedem 'onTouch'-Ereignis wird eine neue' scale 'berechnet (als' newDist/oldDist') und diese Skalierung wird auf 'matrix' angewendet, was eine totale_Skala als matrix_current_scale multipliziert mit current_scale ergibt. Beim nächsten Berührungsereignis wird dieser Prozess wiederholt (möglicherweise wird ein Gesamt_Scale größer als der MAX_ZOOM gegeben). – ALiGOTec

1

Erstellen Sie eine temporäre Matrix (temp), darin die aktuelle Matrix speichern und Scal die temporäre Matrix. Überprüfen Sie dann den MSCALE_X-Wert der temporären Matrix.

Wenn der Zoom Ihrer Temp-Matrix innerhalb Ihres Grenzwerts liegt, skalieren Sie Ihre Matrix nach und speichern Sie sie in einer anderen Matrix (savedMatrixZoom). Wenn es über Ihrem Limit liegt, laden Sie einfach Ihre aktuelle Matrix von SavedMatrixZoom.

else if (mode == ZOOM) { 
     float newDist = spacing(event); 
     Log.d(TAG, "newDist=" + newDist); 
     if (newDist > 10f) { 
      matrix.set(savedMatrix); 
      zoomScale = newDist/oldDist; 

      Matrix temp = new Matrix(); 
      temp.set(matrix); 
      temp.postScale(zoomScale, zoomScale, mid.x, mid.y); 
      mapZoom = getValue(temp, Matrix.MSCALE_X); 
      if (mapZoom < MAX_ZOOM && mapZoom > MIN_ZOOM) { 
       matrix.postScale(zoomScale, zoomScale, mid.x, mid.y); 
       savedMatrixZoom.set(matrix); 
      } else { 
       matrix.set(savedMatrixZoom); 
      } 
     } 
    } 

Hoffe, dass es

+0

plese explation getValue (temp, Matrix.MSCALE_X) Methode .. – Umesh

+0

plese explaion getValue (temp, Matrix.MSCALE_X) Methode. –

1
if(mapZoom > MAX_ZOOM && (newDist > oldDist)) { 
    break; 
} else if(mapZoom < MIN_Zoom && (newDist < oldDist)){ 
    break; 
} 

matrix.postScale(zoomScale, zoomScale, mid.x, mid.y); 
savedMatrixZoom.set(matrix); 

hilft es funktioniert gut, aber immer noch ich locker die Glätte und zu empfindlich ist.

Verwandte Themen