Android Open Source - Operation-Valkyrie Touch Image View






From Project

Back to project page Operation-Valkyrie.

License

The source code is released under:

Terms and conditions Preamble: This Agreement, signed on Jun 10, 2012 [hereinafter: Effective Date] governs the relationship between the Enduser, a private person, (hereinafter: Licensee) and Paul N...

If you think the Android project Operation-Valkyrie listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * TouchImageView.java/*from  w  w w.j  av  a2s  .co m*/
 * By: Michael Ortiz
 * Updated By: Patrick Lackemacher
 * Updated By: Paul Neuhold, Laurenz Theuerkauf, Alexander Ritz, Jakob Schweighofer, Milo Tischler
 * -------------------
 * Extends Android ImageView to include pinch zooming and panning.
 */

package valkyrie.widget;

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

public class TouchImageView extends ImageView {

  private String TAG = "TouchImageView";
  Matrix matrix = new Matrix();

  // 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;
  float myWidth, myHeight = 0;
  PointF translateP = new PointF();
  PointF myMid = new PointF();
  PointF bmMid = new PointF();
  // Remember some things for zooming
  PointF last = new PointF();
  PointF start = new PointF();
  float minScale = 1f;
  float maxScale = 3f;
  float[] m;

  float redundantXSpace, redundantYSpace;

  float width, height;
  static final int CLICK = 3;
  float saveScale = 1f;
  float right, bottom, origWidth, origHeight, bmWidth, bmHeight;

  ScaleGestureDetector mScaleDetector;
  GestureDetector mGestureDetector;

  Context context;

  public TouchImageView(Context context) {
    super(context);
    sharedConstructing(context);
  }

  public TouchImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    sharedConstructing(context);
  }

  private void sharedConstructing(Context context) {
    super.setClickable(true);
    this.context = context;
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    mGestureDetector = new GestureDetector(context, new GestureListener());
    matrix.setTranslate(1f, 1f);
    m = new float[9];
    setImageMatrix(matrix);
    setScaleType(ScaleType.MATRIX);

    setOnTouchListener(new OnTouchListener() {

      public boolean onTouch(View v, MotionEvent event) {
        mScaleDetector.onTouchEvent(event);
        mGestureDetector.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()) {
        case MotionEvent.ACTION_DOWN:
          last.set(event.getX(), event.getY());
          start.set(last);
          mode = DRAG;
          break;
        case MotionEvent.ACTION_MOVE:
          if (mode == DRAG) {
            float deltaX = curr.x - last.x;
            float deltaY = curr.y - last.y;
            float scaleWidth = Math.round(origWidth * saveScale);
            float scaleHeight = Math.round(origHeight * saveScale);
            if (scaleWidth < width) {
              deltaX = 0;
              if (y + deltaY > 0)
                deltaY = -y;
              else if (y + deltaY < -bottom)
                deltaY = -(y + bottom);
            } else if (scaleHeight < height) {
              deltaY = 0;
              if (x + deltaX > 0)
                deltaX = -x;
              else if (x + deltaX < -right)
                deltaX = -(x + 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);
            }
            matrix.postTranslate(deltaX, deltaY);
            last.set(curr.x, curr.y);
          }
          break;

        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;

        case MotionEvent.ACTION_POINTER_UP:
          mode = NONE;
          break;
        }
        setImageMatrix(matrix);
        invalidate();
        return true; // indicate event was handled
      }

    });
  }

  @Override
  public void setImageBitmap(Bitmap bm) {
    super.setImageBitmap(bm);
    if (bm != null) {
      bmWidth = bm.getWidth();
      bmHeight = bm.getHeight();
      Log.d(TAG, " bmWIdth  :" + bmWidth);
      Log.d(TAG, " bmHeight :" + bmHeight);
    }
  }
  
  public void setMaxZoom(float x) {
    maxScale = x;
  }

  private class GestureListener extends
      GestureDetector.SimpleOnGestureListener {

    @Override
    public boolean onDown(MotionEvent e) {
      return true;
    }

    // event when double tap occurs
    @Override
    public boolean onDoubleTap(MotionEvent e) {
      float x = e.getX();
      float y = e.getY();

 
      setScaleType(ScaleType.CENTER_INSIDE);

      Log.d("Double Tap", "Tapped at: (" + x + "," + y + ")");
      setScaleType(ScaleType.MATRIX);
      return true;
    }
  }

  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;
        setScaleType(ScaleType.CENTER_INSIDE);
        setScaleType(ScaleType.MATRIX);

        // the image
      }
      right = width * saveScale - width
          - (2 * redundantXSpace * saveScale);
      bottom = height * saveScale - height
          - (2 * redundantYSpace * saveScale);
      if (origWidth * saveScale <= width
          || origHeight * saveScale <= height) {
        setScaleType(ScaleType.MATRIX);
        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);
    Log.d(TAG, "width: " + width);
    Log.d(TAG, "height: " + height);
    // Fit to screen.
    float scale;
    float scaleX = (float) width / (float) bmWidth;
    float scaleY = (float) height / (float) bmHeight;
    scale = Math.min(scaleX, scaleY);
    matrix.setScale(scale, scale);
    setImageMatrix(matrix);
    saveScale = 1f;

    
    // Center the image
    redundantYSpace = (float) height - (scale * (float) bmHeight);
    redundantXSpace = (float) width - (scale * (float) bmWidth);
    redundantYSpace /= (float) 2;
    redundantXSpace /= (float) 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);
  }
}




Java Source Code List

org.opencv.android.Utils.java
org.opencv.calib3d.Calib3d.java
org.opencv.calib3d.StereoBM.java
org.opencv.calib3d.StereoSGBM.java
org.opencv.core.Algorithm.java
org.opencv.core.Core.java
org.opencv.core.CvException.java
org.opencv.core.CvType.java
org.opencv.core.MatOfByte.java
org.opencv.core.MatOfDMatch.java
org.opencv.core.MatOfDouble.java
org.opencv.core.MatOfFloat4.java
org.opencv.core.MatOfFloat6.java
org.opencv.core.MatOfFloat.java
org.opencv.core.MatOfInt4.java
org.opencv.core.MatOfInt.java
org.opencv.core.MatOfKeyPoint.java
org.opencv.core.MatOfPoint2f.java
org.opencv.core.MatOfPoint3.java
org.opencv.core.MatOfPoint3f.java
org.opencv.core.MatOfPoint.java
org.opencv.core.MatOfRect.java
org.opencv.core.Mat.java
org.opencv.core.Point3.java
org.opencv.core.Point.java
org.opencv.core.Range.java
org.opencv.core.Rect.java
org.opencv.core.RotatedRect.java
org.opencv.core.Scalar.java
org.opencv.core.Size.java
org.opencv.core.TermCriteria.java
org.opencv.features2d.DMatch.java
org.opencv.features2d.DescriptorExtractor.java
org.opencv.features2d.DescriptorMatcher.java
org.opencv.features2d.FeatureDetector.java
org.opencv.features2d.Features2d.java
org.opencv.features2d.GenericDescriptorMatcher.java
org.opencv.features2d.KeyPoint.java
org.opencv.highgui.Highgui.java
org.opencv.highgui.VideoCapture.java
org.opencv.imgproc.Imgproc.java
org.opencv.imgproc.Moments.java
org.opencv.imgproc.Subdiv2D.java
org.opencv.ml.CvANN_MLP_TrainParams.java
org.opencv.ml.CvANN_MLP.java
org.opencv.ml.CvBoostParams.java
org.opencv.ml.CvBoost.java
org.opencv.ml.CvDTreeParams.java
org.opencv.ml.CvDTree.java
org.opencv.ml.CvERTrees.java
org.opencv.ml.CvGBTreesParams.java
org.opencv.ml.CvGBTrees.java
org.opencv.ml.CvKNearest.java
org.opencv.ml.CvNormalBayesClassifier.java
org.opencv.ml.CvParamGrid.java
org.opencv.ml.CvRTParams.java
org.opencv.ml.CvRTrees.java
org.opencv.ml.CvSVMParams.java
org.opencv.ml.CvSVM.java
org.opencv.ml.CvStatModel.java
org.opencv.ml.EM.java
org.opencv.ml.Ml.java
org.opencv.objdetect.CascadeClassifier.java
org.opencv.objdetect.HOGDescriptor.java
org.opencv.objdetect.Objdetect.java
org.opencv.photo.Photo.java
org.opencv.utils.Converters.java
org.opencv.video.BackgroundSubtractorMOG.java
org.opencv.video.BackgroundSubtractor.java
org.opencv.video.KalmanFilter.java
org.opencv.video.Video.java
valkyrie.colorpicker.ColorPickerDialog.java
valkyrie.colorpicker.ColorPicker.java
valkyrie.file.DecodeBitmaps.java
valkyrie.file.FileManager.java
valkyrie.filter.FilterAssets.java
valkyrie.filter.FilterInternalStorage.java
valkyrie.filter.FilterManager.java
valkyrie.filter.FilterUIPosition.java
valkyrie.filter.IFilter.java
valkyrie.filter.ascii.Ascii.java
valkyrie.filter.ascii.Converter.java
valkyrie.filter.ascii.Font.java
valkyrie.filter.ascii.Options.java
valkyrie.filter.canny.Canny.java
valkyrie.filter.grayscale.Grayscale.java
valkyrie.filter.nofilter.NoFilter.java
valkyrie.ui.IUpdateableUI.java
valkyrie.ui.LayoutManager.java
valkyrie.ui.MainActivity.java
valkyrie.ui.UpdateableRelativeLayout.java
valkyrie.ui.gallery.AboutActivity.java
valkyrie.ui.gallery.GalleryActivity.java
valkyrie.ui.gallery.ImageAdapter.java
valkyrie.ui.gallery.ShowPicActivity.java
valkyrie.ui.preview.CameraPreviewViewCV.java
valkyrie.widget.MultiDirectionSlidingDrawer.java
valkyrie.widget.TouchImageView.java