2010-09-28 21 views
8

Pinch-Zoom için Max ve Min yakınlaştırma düzeyleri nasıl ayarlanır? //Android'in tutam zoom üzerindeki ölçek sınırları

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

Nasıl uygulandığınıza bağlı olarak değişir. Bazı kodları görebilir miyiz? – fredley

+0

İşte benim kodum: – Audum

cevap

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

İndirgenmiş. Bu, bir eylemin ölçeğini sınırlar (yakınlaştırma hareketi). Birden çok eylem ile kullanıcı, maksimum veya minimum zumun ötesine ölçeklenebilir. – ALiGOTec

+0

Üzgünüz, takip etmiyorum. Birden fazla işlemle ilgili yorumunuzu ve maksimum veya minimum zumun ötesine nasıl ölçeklenebileceğini ayrıntılı olarak açıklayabilir misiniz? –

+0

Her "onTouch" olayında yeni bir "scale" hesaplanır ("newDist/oldDist" olarak) ve bu ölçek "matrix" e uygulanır; bu, current_scale ile çarpılarak matrix_current_scale olarak toplam_scale değeri verir. Bir sonraki dokunma olayında bu işlem tekrarlanır (muhtemelen MAX_ZOOM'dan toplam bir derecelendirme puanı verir). – ALiGOTec

1

, geçici matrisi (geçici) oluştur bunun mevcut matris kaydetmek ve geçici matrisi scal:


İşte benim kodudur. Daha sonra geçici matrisin MSCALE_X değerini kontrol edin.

Temp matrisinizin yakınlaştırması sınırınızdaysa, matrisinizi postscale edin ve başka bir matriste (savedMatrixZoom) kaydedin. Sınırınızın üzerindeyse, mevcut matrisinizi SavedMatrixZoom'dan yükleyin.

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); 
      } 
     } 
    } 

o Düzgün çalışır

+0

plese açıklaması getValue (temp, Matrix.MSCALE_X) yöntemi .. – Umesh

+0

plese explation getValue (temp, Matrix.MSCALE_X) yöntemi. –

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); 

yardımcı Umut ama hala pürüzsüzlük ve çok hassas olduğunu kaybederler.

İlgili konular