您的位置:首页 > 移动开发 > Android开发

安卓运用matrix进行图片的拖动和缩放

2015-01-11 22:06 190 查看
1.matrix讲解

Matrix的对图像的处理可分为四类基本变换:

Translate           平移变换

Rotate                旋转变换

Scale                  缩放变换

Skew                  错切变换

针对每种变换,Android提供了pre、set和post三种操作方式。其中

set用于设置Matrix中的值。

pre是先乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。先乘相当于矩阵运算中的右乘。

post是后乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。后乘相当于矩阵运算中的左乘。
除平移变换(Translate)外,旋转变换(Rotate)、缩放变换(Scale)和错切变换(Skew)都可以围绕一个中心点来进行,如果不指定,在默认情况下是围绕(0, 0)来进行相应的变换的。

2.多点触摸

首先需要继承OnTouchListener

在处理单点触摸中,我们一般会用到MotionEvent.ACTION_DOWN、ACTION_UP、ACTION_MOVE,然后可以用一个switch(event.getAction() )语句来分别进行处理。ACTION_DOWN和ACTION_UP就是单点触摸屏幕,按下去和放开的操作,ACTION_MOVE就是手指在屏幕上移动的操作。

在处理多点触摸的过程中,我们还需要用到MotionEvent.ACTION_MASK。一般使用switch(event.getAction() & MotionEvent.ACTION_MASK)就可以处理处理多点触摸的ACTION_POINTER_DOWN和ACTION_POINTER_UP事件。代码调用这个“与”操作以后,当第二个手指按下或者放开,就会触发ACTION_POINTER_DOWN或者ACTION_POINTER_UP事件。

3.代码如下,是照着一个网上的例子写的

package com.example.imagedrag;

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

public class MainActivity extends Activity {
private static final String LOG_TAG = "MY_LOG_TAG";
private ImageView imageView;
private float x0;
private float y0;
private float x1;
private float y1;
private PointF midPoint;
private float d0;
private float d1;
private Matrix matrix = new Matrix();
private Matrix myMatrix = new Matrix();
/** 记录是拖拉照片模式还是放大缩小照片模式 */
private int mode = 0;// 初始状态
/** 拖拉照片模式 */
private static final int MODE_DRAG = 1;
/** 放大缩小照片模式 */
private static final int MODE_ZOOM = 2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

imageView = (ImageView) findViewById(R.id.image_view);
imageView.setOnTouchListener(new OnTouchListener() {
/** 计算两个手指间的距离 */
private float distance(MotionEvent event) {
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
/** 使用勾股定理返回两点之间的距离 */
return FloatMath.sqrt(dx * dx + dy * dy);
}

/** 计算两个手指间的中间点 */
private PointF mid(MotionEvent event) {
float midX = (event.getX(1) + event.getX(0)) / 2;
float midY = (event.getY(1) + event.getY(0)) / 2;
return new PointF(midX, midY);
}

@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mode = MODE_DRAG;
x0 = event.getRawX();
y0 = event.getRawY();
myMatrix.set(imageView.getImageMatrix());
break;
case MotionEvent.ACTION_POINTER_DOWN:
Log.i(LOG_TAG, "ACTION_POINTER_DOWN");
mode = MODE_ZOOM;
/** 计算两个手指间的距离 */
d0 = distance(event);
/** 计算两个手指间的中间点 */
midPoint = mid(event);
myMatrix.set(imageView.getImageMatrix());

break;
case MotionEvent.ACTION_MOVE:
if (mode == MODE_DRAG) {
x1 = event.getRawX();
y1 = event.getRawY();
matrix.set(myMatrix);
matrix.postTranslate(x1 - x0, y1 - y0);
} else if (mode == MODE_ZOOM) {
d1 = distance(event);
float scale = d1 / d0;
matrix.set(myMatrix);
matrix.postScale(scale, scale, midPoint.x, midPoint.y);

}
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_UP:
mode = 0;
break;
default:
break;
}
imageView.setImageMatrix(matrix);
return true;
}
});
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<ImageView android:id="@+id/image_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/bb"
android:scaleType="matrix" />

</RelativeLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息