缩放和拖动利用矩阵图像的android缩放、拖动、矩阵、图像

2023-09-12 06:21:22 作者:很酷不撩妹

我得到了以下code(来自你好受的android版伯内特)工作很好,我能够拖动和缩放的图像。

 进口android.app.Activity;
进口android.graphics.Matrix;
进口android.graphics.PointF;
进口android.os.Bundle;
进口android.util.FloatMath;
进口android.util.Log;
进口android.view.MotionEvent;
进口android.view.View;
进口android.view.View.OnTouchListener;
进口android.widget.ImageView;

公共类触摸扩展活动实现OnTouchListener {
   私有静态最后字符串变量=触摸;
   //这些矩阵将用于移动和放大图像
   字模=新的Matrix();
   矩阵savedMatrix =新的Matrix();

   //我们可以在这3个状态之一
   静态最终诠释无= 0;
   静态最终诠释DRAG = 1;
   静态最终诠释ZOOM = 2;
   INT模式=无;

   //记住一些东西放大
   的PointF开始=新的PointF();
   的PointF中期=新的PointF();
   浮oldDist = 1F;

   @覆盖
   公共无效的onCreate(包savedInstanceState){
      super.onCreate(savedInstanceState);
      的setContentView(R.layout.main);
      ImageView的观点=(ImageView的)findViewById(R.id.imageView);
      view.setOnTouchListener(本);
   }

   @覆盖
   公共布尔onTouch(视图V,MotionEvent事件){
      ImageView的观点=(ImageView的)V;

      //转储触摸事件日志
      dumpEvent(事件);

      //这里处理触摸事件...
      开关(event.getAction()及MotionEvent.ACTION_MASK){
      案例MotionEvent.ACTION_DOWN:
         savedMatrix.set(矩阵);
         start.set(event.getX(),event.getY());
         Log.d(TAG模式= DRAG);
         模式=阻力;
         打破;
      案例MotionEvent.ACTION_POINTER_DOWN:
         oldDist =间距(事件);
         Log.d(TAG,oldDist =+ oldDist);
         如果(oldDist> 10F){
            savedMatrix.set(矩阵);
            中点(中,事件);
            模式=变焦;
            Log.d(TAG模式= ZOOM);
         }
         打破;
      案例MotionEvent.ACTION_UP:
      案例MotionEvent.ACTION_POINTER_UP:
         模式=无;
         Log.d(TAG模式= NONE);
         打破;
      案例MotionEvent.ACTION_MOVE:
         如果(模式==拖动){
            // ...
            matrix.set(savedMatrix);
            matrix.postTranslate(event.getX() -  start.x,
                  event.getY() -  start.y);
         }
         否则,如果(模式==变焦){
            浮newDist =间距(事件);
            Log.d(TAG,newDist =+ newDist);
            如果(newDist> 10F){
               matrix.set(savedMatrix);
               浮规模= newDist / oldDist;
               matrix.postScale(规模化,规模化,mid.x,mid.y);
            }
         }
         打破;
      }

      view.setImageMatrix(矩阵);
      返回true; //表示事件已经被处理
   }

   / **显​​示在LogCat中查看事件,调试* /
   私人无效dumpEvent(MotionEvent事件){
      字符串名称[] = {DOWN,UP,移动,取消,外,
            POINTER_DOWN,POINTER_UP,7?,8?,9? };
      StringBuilder的SB =新的StringBuilder();
      INT行动= event.getAction();
      INT行动code =动作和放大器; MotionEvent.ACTION_MASK;
      sb.append(事件响应_)追加(姓名[动作code])。
      如果(动作code == MotionEvent.ACTION_POINTER_DOWN
            ||行动code == MotionEvent.ACTION_POINTER_UP){
         sb.append((PID).append(
               作用>> MotionEvent.ACTION_POINTER_ID_SHIFT);
         sb.append());
      }
      sb.append([);
      的for(int i = 0; I< event.getPointerCount();我++){
         。sb.append(#)追加(ⅰ);
         sb.append((PID).append(event.getPointerId(ⅰ));
         sb.append()=)追加((int)的event.getX(ⅰ))。
         。sb.append(,)追加((int)的event.getY(ⅰ));
         如果第(i + 1&其中; event.getPointerCount())
            sb.append(;);
      }
      sb.append(]);
      Log.d(TAG,sb.toString());
   }

   / **确定第一两个手指之间的空间* /
   私人浮动间距(MotionEvent事件){
      浮X = event.getX(0) -  event.getX(1);
      浮Y = event.getY(0) -  event.getY(1);
      返回FloatMath.sqrt(X * X + Y * Y);
   }

   / **计算前两个手指的中点* /
   私人无效中点(的PointF点,MotionEvent事件){
      浮X = event.getX(0)+ event.getX(1);
      浮Y = event.getY(0)+ event.getY(1);
      point.set(X / 2,Y / 2);
   }
}
 

不过,可以some1好心在上述范围内code解释清楚以下5条线的功能是什么?

  savedMatrix.set(矩阵);
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() -  start.x,event.getY() -  start.y);
浮规模= newDist / oldDist;
matrix.postScale(规模化,规模化,mid.x,mid.y);
 

在此先感谢您的解释:)

解决方案

  savedMatrix.set(矩阵);
 
利用拖动功能快速选择图片压缩功能介绍

复制黑客帝国的内容为savedMatrix

  matrix.postTranslate(event.getX() -  start.x,event.getY() -  start.y);
 

矩阵确定了一些改造,如缩放和移动。 的postTranslate,增加了移动转型,转型中的矩阵已定义。即黑客帝国包含了一些缩放变换,再经过申请的postTranslate这将决定变焦而后动的转变。

 浮法规模= newDist / oldDist;
matrix.postScale(规模化,规模化,mid.x,mid.y);
 

添加缩放改造与中心(mid.x,mid.y)在黑客帝国

已经定义的转换

i got the following code (from Hello android by Ed Burnette) working nicely and i am able to drag and zoom for an image.

import android.app.Activity;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class Touch extends Activity implements OnTouchListener {
   private static final String TAG = "Touch";
   // These matrices will be used to move and zoom image
   Matrix matrix = new Matrix();
   Matrix savedMatrix = 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;

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

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      ImageView view = (ImageView) findViewById(R.id.imageView);
      view.setOnTouchListener(this);
   }

   @Override
   public boolean onTouch(View v, MotionEvent event) {
      ImageView view = (ImageView) v;

      // Dump touch event to log
      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:
      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);
            }
         }
         break;
      }

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

   /** Show an event in the LogCat view, for debugging */
   private void dumpEvent(MotionEvent event) {
      String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
            "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
      StringBuilder sb = new StringBuilder();
      int action = event.getAction();
      int actionCode = action & MotionEvent.ACTION_MASK;
      sb.append("event ACTION_").append(names[actionCode]);
      if (actionCode == MotionEvent.ACTION_POINTER_DOWN
            || actionCode == MotionEvent.ACTION_POINTER_UP) {
         sb.append("(pid ").append(
               action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
         sb.append(")");
      }
      sb.append("[");
      for (int i = 0; i < event.getPointerCount(); i++) {
         sb.append("#").append(i);
         sb.append("(pid ").append(event.getPointerId(i));
         sb.append(")=").append((int) event.getX(i));
         sb.append(",").append((int) event.getY(i));
         if (i + 1 < event.getPointerCount())
            sb.append(";");
      }
      sb.append("]");
      Log.d(TAG, sb.toString());
   }

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

however, can some1 kindly explain clearly the functions of the following 5 lines within the above code?

savedMatrix.set(matrix);
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x,event.getY() - start.y);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);

thanks in advance for the explanation :)

解决方案

savedMatrix.set(matrix);

copying "matrix" content into "savedMatrix"

matrix.postTranslate(event.getX() - start.x,event.getY() - start.y);

"matrix" determines some transformation, like zoom and move. "postTranslate" adds "move" transformation to transformation already defined in "matrix". I.e. "matrix" contains some zoom transformation, and then after applying postTranslate it will determine "zoom and then move" transformation.

float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);

Adding zoom transformation with center in (mid.x, mid.y) to transformation already defined in "matrix"