图片随手势的拖拽、缩放、旋转

来源:互联网 发布:淘宝招人 编辑:程序博客网 时间:2024/06/05 20:32

 在Android应用中,图片随手势的拖拽、缩放、旋转在很多场景中都会用到,今天我们要做的就是在ImageView的基础上实现一个可以拖拽、缩放、转转的TouchView。

         

             一、实现原理

             OnTouch事件捕捉+Matrix矩阵变换


           二、核心方法

       拖拽:Matrix.postTranslate(DeltalX, DeltalY);

            缩放:Matrix.postScale(mScale, mScale, mPoint.x, mPoint.y);

            旋转:Matrix.postRotate(Angle, mPoint.x, mPoint.y);


            三、具体实现

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. package com.Android.TouchView;  
  2.   
  3. /*  
  4.  * Android多点触控技术练习  
  5.  * @Author:Robin  
  6.  * @Date:2013年12月29日  
  7.  * @边界处理暂时不知道怎么写啊  
  8.  * 目前的问题有:  
  9.  * 手势识别不是很顺畅,经常出现该放缩时放缩不了的情况  
  10.  * 由于没有边界判断,程序可能会出现崩溃  
  11.  */  
  12.    
  13. import android.annotation.SuppressLint;  
  14. import android.app.Activity;  
  15. import android.graphics.Bitmap;  
  16. import android.graphics.Bitmap.Config;  
  17. import android.graphics.BitmapFactory;  
  18. import android.graphics.Canvas;  
  19. import android.graphics.Matrix;  
  20. import android.graphics.Paint;  
  21. import android.graphics.PaintFlagsDrawFilter;  
  22. import android.graphics.PointF;  
  23. import android.util.DisplayMetrics;  
  24. import android.util.FloatMath;  
  25. import android.view.MotionEvent;  
  26. import android.widget.ImageView;  
  27.   
  28. @SuppressLint({ "ViewConstructor", "FloatMath" })  
  29. public class MultiTouchView extends ImageView  
  30. {  
  31.   
  32.   
  33.     //本地图像资源  
  34.     private int mDrawable;  
  35.     //图像位图  
  36.     private Bitmap mBitmap;  
  37.     //屏幕宽度  
  38.     private int ScreenWidth;  
  39.     //屏幕高度  
  40.     private int ScreenHeight;  
  41.     //原始图像矩阵  
  42.     private Matrix mMatrix=new Matrix();  
  43.     //过程图像矩阵  
  44.     private Matrix mSavedMatrix=new Matrix();  
  45.     //结果图像矩阵  
  46.     private Matrix mResultMatrix=new Matrix();  
  47.     //定义三种模式:None、Drag、Zoom  
  48.     public static final int Mode_None=0;  
  49.     public static final int Mode_Drag=1;  
  50.     public static final int Mode_Zoom=2;  
  51.     //当前操作模式  
  52.     private int mMode=Mode_None;  
  53.     //当前坐标  
  54.     private float mDownX,mDownY;  
  55.     //存储两点间的距离  
  56.     private float mDistance=0f;  
  57.     //存储旋转角  
  58.     @SuppressWarnings("unused")  
  59.     private float mAngle=0f;  
  60.     //存储中点  
  61.     private PointF mPoint;  
  62.     //最大缩放比例  
  63.     //private float MaxScale=3f;  
  64.     //最小缩放比例  
  65.     //private float MinScale=0.5f;  
  66.       
  67.     public MultiTouchView(Activity mActivity ,int Drawable)   
  68.     {  
  69.         super(mActivity);  
  70.         //设置当前图片资源  
  71.         this.mDrawable=Drawable;  
  72.         //获取Bitmap  
  73.         mBitmap=BitmapFactory.decodeResource(getResources(), mDrawable);  
  74.         DisplayMetrics dm=new DisplayMetrics();  
  75.         mActivity.getWindowManager().getDefaultDisplay().getMetrics(dm);  
  76.         //获取屏幕宽度和高度  
  77.         ScreenWidth=dm.widthPixels;  
  78.         ScreenHeight=dm.heightPixels;  
  79.         mMatrix=new Matrix();  
  80.     }  
  81.   
  82.     @SuppressLint("DrawAllocation")  
  83.     @Override  
  84.     protected void onDraw(Canvas canvas)   
  85.     {  
  86.         //消除图像锯齿  
  87.         canvas.setDrawFilter(new PaintFlagsDrawFilter(0,Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));  
  88.         canvas.save();  
  89.         //绘制图像  
  90.         canvas.drawBitmap(mBitmap, mMatrix, null);  
  91.         canvas.restore();  
  92.     }  
  93.       
  94.     @Override  
  95.     public boolean onTouchEvent(MotionEvent Event)  
  96.     {  
  97.         switch(Event.getAction())  
  98.         {  
  99.         //单点触控处理  
  100.           case MotionEvent.ACTION_DOWN:  
  101.               //设置当前操作模式为Drag  
  102.               mMode=Mode_Drag;  
  103.               //获取当前坐标  
  104.               mDownX=Event.getX();  
  105.               mDownY=Event.getY();  
  106.               mSavedMatrix.set(mMatrix);  
  107.               break;  
  108.         //多点触控处理  
  109.           case MotionEvent.ACTION_POINTER_DOWN:  
  110.                  mMode=Mode_Zoom;  
  111.                  //获取两点间距离  
  112.                  mDistance=getDistance(Event);  
  113.                  //获取旋转角  
  114.                  mAngle=getAngle(Event);  
  115.                  //获取中点  
  116.                  mPoint=getMidPoint(Event);  
  117.                  mSavedMatrix.set(mMatrix);  
  118.               break;  
  119.           case MotionEvent.ACTION_MOVE:  
  120.               //缩放处理  
  121.               if(mMode==Mode_Zoom)  
  122.               {  
  123.                   mResultMatrix.set(mSavedMatrix);  
  124.                   //获取缩放比率  
  125.                   float mScale=getDistance(Event)/mDistance;  
  126.                   //获取旋转角,这里可以不用  
  127.                   //float Angle=getAngle(Event)-mAngle;  
  128.                   //以中点为中心,进行缩放  
  129.                   mResultMatrix.postScale(mScale, mScale, mPoint.x, mPoint.y);  
  130.                   //以中点为中心,进行旋转,这里可以不用  
  131.                   //mResultMatrix.postRotate(Angle, mPoint.x, mPoint.y);  
  132.                   mMatrix.set(mResultMatrix);  
  133.                   invalidate();  
  134.               }else if(mMode==Mode_Drag)//平移处理  
  135.               {  
  136.                   mResultMatrix.set(mSavedMatrix);  
  137.                   //计算平移量  
  138.                   float DeltalX=Event.getX()-mDownX;  
  139.                   float DeltalY=Event.getY()-mDownY;  
  140.                   //平移  
  141.                   mResultMatrix.postTranslate(DeltalX, DeltalY);  
  142.                   mMatrix.set(mResultMatrix);  
  143.                   invalidate();  
  144.               }  
  145.               break;  
  146.             
  147.           case MotionEvent.ACTION_UP:  
  148.              //这里要不要处理呢,如果需要,怎么办  
  149.           case MotionEvent.ACTION_POINTER_UP:  
  150.                 mMode = Mode_None;  
  151.                 break;  
  152.         }  
  153.         return true;  
  154.     }  
  155.   
  156.     //返回两点间的距离  
  157.     public float getDistance(MotionEvent Event)  
  158.     {  
  159.         //计算X的变化量  
  160.         float DeltalX=Event.getX(0)-Event.getX(1);  
  161.         //计算Y的变化量  
  162.         float DeltalY=Event.getY(0)-Event.getY(1);  
  163.         //计算距离  
  164.         return FloatMath.sqrt(DeltalX*DeltalX+DeltalY*DeltalY);  
  165.     }  
  166.       
  167.     //返回两点的中点  
  168.     @SuppressLint("FloatMath")  
  169.     public PointF getMidPoint(MotionEvent Event)  
  170.     {  
  171.         float X=Event.getX(0)+Event.getX(1);  
  172.         float Y=Event.getY(0)+Event.getY(1);  
  173.         return new PointF(X/2,Y/2);  
  174.     }  
  175.       
  176.     //获得旋转角  
  177.     public float getAngle(MotionEvent Event)  
  178.     {  
  179.         double DeltalX=Event.getX(0)-Event.getX(1);  
  180.         double DeltalY=Event.getY(0)-Event.getY(1);  
  181.         return (float)Math.atan2(DeltalX, DeltalY);  
  182.     }  
  183.       
  184.     //边界处理,暂时没找到比较好的方法  
  185.     public boolean CheckBounary()  
  186.     {  
  187.         return false;  
  188.     }  
  189.       
  190.     //存储当前图片  
  191.     public Bitmap SaveImage()  
  192.     {  
  193.         Bitmap mBitmap = Bitmap.createBitmap(ScreenWidth, ScreenHeight,Config.ARGB_8888);  
  194.         Canvas mCanvas = new Canvas(mBitmap);   
  195.         mCanvas.drawBitmap(mBitmap, mMatrix, null);  
  196.         mCanvas.save(Canvas.ALL_SAVE_FLAG);  
  197.         mCanvas.restore();  
  198.         return mBitmap;  
  199.     }  
  200. }  

     

       四、 运行效果



0 0
原创粉丝点击