Android 图片旋转 缩放 平移

Android 图片旋转 缩放 平移

图片的变化主要是matrix的变化,对matrix不懂的可以先了解下matrxi.

public class FunnyView extends View {

      /*
      * 手指按下时可能是移动 也可能是拖动
      */
      private static final int ZOOM = -1 ;
      private static final int DRAG = 1;
      private int mode = 0;
      // 第一个触控点
      private PointF startPointF = new PointF ();
      // 第二个触控点
      private PointF mCurMovePointF = new PointF ();


      private float mDegree ;
      private float mScale ;


      private Bitmap mBitmap = null;
      private Matrix mMatrix = null;
      private Paint mPaint = null;
      // bitmap的中心点
      private PointF mCenterPoint = new PointF ();


      public FunnyView (Context context ) {
           this (context , null, 0 );
      }


      public FunnyView (Context context , AttributeSet attrs , int defStyle ) {
           super (context , attrs , defStyle );
           init() ;
      }


      private void init() {
          mBitmap = BitmapFactory .decodeResource (getResources (), R .drawable .pic1 );
          mMatrix = new Matrix ();
          mPaint = new Paint ();
          mPaint .setColor (Color .BLUE );
          mPaint .setStrokeWidth (10 );
          mPaint .setAntiAlias ( true) ;
           // 计算bitmap中心点坐标
          mCenterPoint .set (mBitmap .getWidth () / 2, mBitmap. getHeight() / 2 );
      }


      @Override
      protected void onDraw( Canvas canvas ) {
           canvas .drawBitmap (mBitmap , mMatrix , mPaint );
           super. onDraw (canvas );
      }


      /*
      * 计算角度和缩放
      *
      * 这里使用余弦定理计算 容易理解
      * 如果对android矩阵matrix底层原理清楚的同学
      * 可以使用matrix计算出旋转角度和缩放量
      */
      private void getRotationScale() {
           // 角度
           double a = distance4PointF (mCenterPoint , startPointF) ;
           double b = distance4PointF (startPointF , mCurMovePointF) ;
           double c = distance4PointF (mCenterPoint , mCurMovePointF) ;


           double cosb = ( a * a + c * c - b * b) / ( 2 * a * c) ;


           if ( cosb >= 1) {
              cosb = 1f;
           }
           double radian = Math . acos( cosb) ;
           float newDegree = ( float ) radianToDegree (radian );


           PointF centerToStartMove = new PointF ((startPointF .x - mCenterPoint .x ),
                    (startPointF .y - mCenterPoint .y ));


           PointF centerToCurMove = new PointF(
                    (mCurMovePointF .x - mCenterPoint .x ),
                    (mCurMovePointF .y - mCenterPoint .y ));


           // 向量叉乘结果, 如果结果为负数, 表示为逆时针, 结果为正数表示顺时针
           float result = centerToStartMove .x * centerToCurMove. y
                    - centerToStartMove .y * centerToCurMove. x;


           if ( result < 0) {
              newDegree = -newDegree ;
           }


          mDegree = newDegree ;
          mScale = ( float) ( c / a) ;
      }


      /**
      * 弧度换算成角度
      *
      * @return
      */
      public static double radianToDegree( double radian ) {
           return radian * 180 / Math .PI ;
      }


      /**
      * 两个点之间的距离
      */
      private float distance4PointF( PointF pf1, PointF pf2 ) {
           float disX = pf2 .x - pf1. x;
           float disY = pf2 .y - pf1. y;
           return FloatMath . sqrt( disX * disX + disY * disY) ;
      }


      @Override
      public boolean onTouchEvent( MotionEvent event ) {
           switch ( event .getAction () & MotionEvent .ACTION_MASK ) {
           case MotionEvent .ACTION_DOWN :
               // 注意getX()和getRawX()的区别
              startPointF .set (event .getX (), event .getY ());
              mode = DRAG ;
               break;
           case MotionEvent .ACTION_MOVE :
               if ( mode == DRAG ) {
                    float x = event .getX () - startPointF. x;
                    float y = event .getY () - startPointF. y;
                   mCenterPoint .x = mCenterPoint .x + x ;
                   mCenterPoint .y = mCenterPoint .y + y ;
                   startPointF .set (event .getX (), event .getY ());
                   mMatrix .postTranslate (x , y );


               } else if ( mode == ZOOM ) {
                   mCurMovePointF .set (event .getX (), event .getY ());
                    getRotationScale ();
                    /*
                    * 旋转和缩放的中心点都是bitmap的中心点,根据需求可以更改。
                    */
                    // 旋转
                   mMatrix .postRotate (mDegree , mCenterPoint. x, mCenterPoint .y );
                    // 缩放
                   mMatrix .postScale (mScale , mScale , mCenterPoint. x,
                             mCenterPoint .y );
                    // 重新赋值起始点
                   startPointF .set (mCurMovePointF );
               }
               break;
           case MotionEvent .ACTION_POINTER_DOWN :
              mode = ZOOM ;
               break;
           case MotionEvent .ACTION_POINTER_UP :
              mode = 0;
               break;
           case MotionEvent .ACTION_CANCEL :
              mode = 0;
               break;
           }
           invalidate ();
           // 返回true 事件不再往下分发
           return true ;
      }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值