标签:
图片的变化主要是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 ; } }
标签:
原文地址:http://www.cnblogs.com/Theone2014/p/4828491.html