2015-11-23 8 views
7

में स्क्रीन सीमा के साथ छविदृश्य रोटेशन लागू करें मैं छवि ज़ूमिंग, ड्रैग, रोटेशन के लिए स्क्रीन सीमा के बाहर एक एंड्रॉइड एप्लिकेशन विकसित कर रहा हूं। सबसे पहले मुझे पूरी स्क्रीन पर छवि को प्रोग्रामेटिक रूप से फिट करना होगा और स्क्रीन सीमा के बाहर छवि पर ज़ूमिंग, रोटेशन, ड्रैग ऑपरेशन करना होगा। मैंने निम्नलिखित कोड का उपयोग किया, सब कुछ ठीक काम कर रहा है जो मुझे की आवश्यकता है सिवाय इसके कि रोटेशन सुविधा। मैंने मैट्रिक्स गणना को भ्रमित कर दिया है, इसलिए कृपया इस कोड के साथ घुमावदार सुविधा को कार्यान्वित करने में सहायता करें।नीचे की कक्षा

JavaCode:

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Matrix; 
import android.graphics.PointF; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.ScaleGestureDetector; 
import android.view.View; 
import android.widget.ImageView; 

public class ZoomableImageView extends ImageView 
{ 
    Matrix matrix = new Matrix(); 

    static final int NONE = 0; 
    static final int DRAG = 1; 
    static final int ZOOM = 2; 
    static final int CLICK = 3; 
    int mode = NONE; 

    PointF last = new PointF(); 
    PointF start = new PointF(); 
    float minScale = 1f; 
    float maxScale = 4f; 
    float[] m; 

    float redundantXSpace, redundantYSpace; 
    float width, height; 
    float saveScale = 1f; 
    float right, bottom, origWidth, origHeight, bmWidth, bmHeight; 

    ScaleGestureDetector mScaleDetector; 
    Context context; 

    public ZoomableImageView(Context context, AttributeSet attr) 
    { 
     super(context, attr); 
     super.setClickable(true); 
     this.context = context; 
     mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
     matrix.setTranslate(1f, 1f); 
     m = new float[9]; 
     setImageMatrix(matrix); 
     setScaleType(ScaleType.MATRIX); 

     setOnTouchListener(new OnTouchListener() 
     { 

      @Override 
      public boolean onTouch(View v, MotionEvent event) 
      { 
       mScaleDetector.onTouchEvent(event); 

       matrix.getValues(m); 
       float x = m[Matrix.MTRANS_X]; 
       float y = m[Matrix.MTRANS_Y]; 
       PointF curr = new PointF(event.getX(), event.getY()); 

       switch (event.getAction()) 
       { 
        //when one finger is touching 
        //set the mode to DRAG 
        case MotionEvent.ACTION_DOWN: 
         last.set(event.getX(), event.getY()); 
         start.set(last); 
         mode = DRAG; 
         break; 
        //when two fingers are touching 
        //set the mode to ZOOM 
        case MotionEvent.ACTION_POINTER_DOWN: 
         last.set(event.getX(), event.getY()); 
         start.set(last); 
         mode = ZOOM; 
         break; 
        //when a finger moves 
        //If mode is applicable move image 
        case MotionEvent.ACTION_MOVE: 
         //if the mode is ZOOM or 
         //if the mode is DRAG and already zoomed 
         if (mode == ZOOM || (mode == DRAG && saveScale > minScale)) 
         { 
          float deltaX = curr.x - last.x;// x difference 
          float deltaY = curr.y - last.y;// y difference 
          float scaleWidth = Math.round(origWidth * saveScale);// width after applying current scale 
          float scaleHeight = Math.round(origHeight * saveScale);// height after applying current scale 
          //if scaleWidth is smaller than the views width 
          //in other words if the image width fits in the view 
          //limit left and right movement 
          if (scaleWidth < width) 
          { 
           deltaX = 0; 
           if (y + deltaY > 0) 
            deltaY = -y; 
           else if (y + deltaY < -bottom) 
            deltaY = -(y + bottom); 
          } 
          //if scaleHeight is smaller than the views height 
          //in other words if the image height fits in the view 
          //limit up and down movement 
          else if (scaleHeight < height) 
          { 
           deltaY = 0; 
           if (x + deltaX > 0) 
            deltaX = -x; 
           else if (x + deltaX < -right) 
            deltaX = -(x + right); 
          } 
          //if the image doesnt fit in the width or height 
          //limit both up and down and left and right 
          else 
          { 
           if (x + deltaX > 0) 
            deltaX = -x; 
           else if (x + deltaX < -right) 
            deltaX = -(x + right); 

           if (y + deltaY > 0) 
            deltaY = -y; 
           else if (y + deltaY < -bottom) 
            deltaY = -(y + bottom); 
          } 
          //move the image with the matrix 
          matrix.postTranslate(deltaX, deltaY); 
          //set the last touch location to the current 
          last.set(curr.x, curr.y); 
         } 
         break; 
        //first finger is lifted 
        case MotionEvent.ACTION_UP: 
         mode = NONE; 
         int xDiff = (int) Math.abs(curr.x - start.x); 
         int yDiff = (int) Math.abs(curr.y - start.y); 
         if (xDiff < CLICK && yDiff < CLICK) 
          performClick(); 
         break; 
        // second finger is lifted 
        case MotionEvent.ACTION_POINTER_UP: 
         mode = NONE; 
         break; 
       } 
       setImageMatrix(matrix); 
       invalidate(); 
       return true; 
      } 

     }); 
    } 

    @Override 
    public void setImageBitmap(Bitmap bm) 
    { 
     super.setImageBitmap(bm); 
     bmWidth = bm.getWidth(); 
     bmHeight = bm.getHeight(); 
    } 

    public void setMaxZoom(float x) 
    { 
     maxScale = x; 
    } 

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener 
    { 

     @Override 
     public boolean onScaleBegin(ScaleGestureDetector detector) 
     { 
      mode = ZOOM; 
      return true; 
     } 

     @Override 
     public boolean onScale(ScaleGestureDetector detector) 
     { 
      float mScaleFactor = detector.getScaleFactor(); 
      float origScale = saveScale; 
      saveScale *= mScaleFactor; 
      if (saveScale > maxScale) 
      { 
       saveScale = maxScale; 
       mScaleFactor = maxScale/origScale; 
      } 
      else if (saveScale < minScale) 
      { 
       saveScale = minScale; 
       mScaleFactor = minScale/origScale; 
      } 
      right = width * saveScale - width - (2 * redundantXSpace * saveScale); 
      bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); 
      if (origWidth * saveScale <= width || origHeight * saveScale <= height) 
      { 
       matrix.postScale(mScaleFactor, mScaleFactor, width/2, height/2); 
       if (mScaleFactor < 1) 
       { 
        matrix.getValues(m); 
        float x = m[Matrix.MTRANS_X]; 
        float y = m[Matrix.MTRANS_Y]; 
        if (mScaleFactor < 1) 
        { 
         if (Math.round(origWidth * saveScale) < width) 
         { 
          if (y < -bottom) 
           matrix.postTranslate(0, -(y + bottom)); 
          else if (y > 0) 
           matrix.postTranslate(0, -y); 
         } 
         else 
         { 
          if (x < -right) 
           matrix.postTranslate(-(x + right), 0); 
          else if (x > 0) 
           matrix.postTranslate(-x, 0); 
         } 
        } 
       } 
      } 
      else 
      { 
       matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY()); 
       matrix.getValues(m); 
       float x = m[Matrix.MTRANS_X]; 
       float y = m[Matrix.MTRANS_Y]; 
       if (mScaleFactor < 1) { 
        if (x < -right) 
         matrix.postTranslate(-(x + right), 0); 
        else if (x > 0) 
         matrix.postTranslate(-x, 0); 
        if (y < -bottom) 
         matrix.postTranslate(0, -(y + bottom)); 
        else if (y > 0) 
         matrix.postTranslate(0, -y); 
       } 
      } 
      return true; 
     } 
    } 

    @Override 
    protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) 
    { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
     width = MeasureSpec.getSize(widthMeasureSpec); 
     height = MeasureSpec.getSize(heightMeasureSpec); 
     //Fit to screen. 
     float scale; 
     float scaleX = width/bmWidth; 
     float scaleY = height/bmHeight; 
     scale = Math.min(scaleX, scaleY); 
     matrix.setScale(scale, scale); 
     setImageMatrix(matrix); 
     saveScale = 1f; 

     // Center the image 
     redundantYSpace = height - (scale * bmHeight) ; 
     redundantXSpace = width - (scale * bmWidth); 
     redundantYSpace /= 2; 
     redundantXSpace /= 2; 

     matrix.postTranslate(redundantXSpace, redundantYSpace); 

     origWidth = width - 2 * redundantXSpace; 
     origHeight = height - 2 * redundantYSpace; 
     right = width * saveScale - width - (2 * redundantXSpace * saveScale); 
     bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); 
     setImageMatrix(matrix); 
    } 
} 
+0

रोटेशन अपने कोड में इस पद्धति को जोड़ने ?? – curiousMind

+0

@Aashvi मुझे किसी कोण पर रोटेशन की आवश्यकता है – Satheesh

उत्तर

3

आप एक मैट्रिक्स का उपयोग करना चाहिए कि ऐसा करने के लिए, के रूप में आप पहले से ही कर रहे हैं, बस postRotate विधि का उपयोग करें।

उदाहरण:

Matrix matrix = new Matrix(); 
imageView.setScaleType(ImageView.ScaleType.MATRIX); 
matrix.postRotate((float) angle, pivotX, pivotY); 
imageView.setImageMatrix(matrix); 

आशा इस मदद करता है।

+0

घूर्णन के लिए यह कोड ठीक काम कर रहा है। मुझे ज़ूम इन, ज़ूम आउट, ड्रैगिंग जैसी अन्य कार्यक्षमताओं के स्नेह के बिना मेरे उपरोक्त कोड के लिए रोटेशन लागू करने की आवश्यकता है। तो जहां मुझे यह कोड लागू करना है। – Satheesh

+0

आपको उसी मैट्रिक्स का उपयोग करना चाहिए जिसका उपयोग आप स्केलिंग के लिए करते हैं, बस जब आप घूमना चाहते हैं तो पोस्टरोटेट को कॉल करें। – Nanoc

+0

मुझे किसी भी कोण पर घूर्णन की आवश्यकता है जबकि उपयोगकर्ता दो अंगुलियों के साथ उपयोग कर रहा है। जहां मुझे अपने कोड में यह कोड लागू करना है। – Satheesh

3

बस किसी भी कोण या केवल उस विशिष्ट कोण आप चाहते हैं पर

public void rotateImage(int degrees, Bitmap mBitmap) { 
    if (mBitmap != null) { 
     Matrix matrix = new Matrix(); 
     matrix.postRotate(degrees); 
     Bitmap bitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true); 
     setImageBitmap(bitmap); 

     mDegreesRotated += degrees; 
     mDegreesRotated = mDegreesRotated % 360; 
    } 
+0

उपरोक्त कोड काम करता है जब हम डिग्री लागू करते हैं। लेकिन मुझे किसी भी कोण पर घूर्णन की आवश्यकता है जबकि उपयोगकर्ता ज़ूमिंग प्रक्रिया की तरह दो अंगुलियों के साथ उपयोग कर रहा है। तो कृपया मुझे बताएं कि मुझे टच लिस्टनर में रोटेशन कोड कहां लागू करना है। – Satheesh

संबंधित मुद्दे