Android利用Matrix实现图片的放大,缩小以及移动控制
2012-06-27 10:00
776 查看
之前见到好多人是用替换ImageView或者用Bitmap的属性设置来实现图片的缩放和移动,这样做会很容易引起虚拟机的OOM错误和不易控制,最重要的是看起来很复杂。
如果直接用ImageView和Matrix呢?
废话不多说,直接上代码,大家看运行效果吧。
布局文件:
好了,到此结束。
程序源码下载
本程序是一个简单的Demo,所以只支持多点触摸进行缩放,测试需在真机中运行,所以,在这里向用模拟器测试的同学表示遗憾。
好了,至此,由于我也是在模拟器中运行,所以,缩放效果无法展示,请大家自测:
如果直接用ImageView和Matrix呢?
废话不多说,直接上代码,大家看运行效果吧。
package sunbo.app.preview; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.RectF; import android.os.Bundle; import android.os.Handler; import android.util.DisplayMetrics; import android.util.FloatMath; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageView; public class ImagePreview extends Activity implements OnTouchListener { private ImageView mImageView; private final Matrix matrix = new Matrix(); private final Matrix savedMatrix = new Matrix(); private DisplayMetrics mDisplyMetrcs; private Bitmap mBitmap; private float minScaleR;// 最小缩放比例 private static final float MAX_SCALE = 4f;// 最大缩放比例 private static final int NONE = 0;// 初始状态 private static final int DRAG = 1;// 拖动 private static final int ZOOM = 2;// 缩放 private int mode = NONE; private final PointF prev = new PointF(); private final PointF mid = new PointF(); private float dist = 1f; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.main); this.setupViews(); } private void setupViews() { // 实例化图片控件 mImageView = (ImageView) this.findViewById(R.id.mImageView); // 引用本地资源文件创建位图对象 mBitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.image); // 将位图对象设置到图片控件中 mImageView.setImageBitmap(mBitmap); // 为图片控件添加触控事件 mImageView.setOnTouchListener(this); // 获取当前屏幕分辨率对象 mDisplyMetrcs = new DisplayMetrics(); this.getWindowManager().getDefaultDisplay().getMetrics(mDisplyMetrcs); this.setMinZoom(); this.setCenter(); new Handler().postDelayed(new Runnable() { public void run() { // 程序启动0.5秒以后设置图片控件的缩放属性 // 如果在描述文件或一开始就设置,那么,图片就会出现在屏幕的左上角,而我们希望图片出现在屏幕的中间位置 mImageView.setScaleType(ImageView.ScaleType.MATRIX); } }, 500); mImageView.setImageMatrix(matrix); } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { // 主点按下 case MotionEvent.ACTION_DOWN: savedMatrix.set(matrix); prev.set(event.getX(), event.getY()); mode = DRAG; break; // 副点按下 case MotionEvent.ACTION_POINTER_DOWN: dist = spacing(event); // 如果连续两点距离大于10,则判定为多点模式 if (spacing(event) > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { matrix.set(savedMatrix); matrix.postTranslate(event.getX() - prev.x, event.getY() - prev.y); } else if (mode == ZOOM) { float newDist = spacing(event); if (newDist > 10f) { matrix.set(savedMatrix); float tScale = newDist / dist; matrix.postScale(tScale, tScale, mid.x, mid.y); } } break; } mImageView.setImageMatrix(matrix); this.checkView(); return true; } private void checkView() { float p[] = new float[9]; matrix.getValues(p); if (mode == ZOOM) { if (p[0] < minScaleR) matrix.setScale(minScaleR, minScaleR); if (p[0] > MAX_SCALE) matrix.set(savedMatrix); } this.setCenter(); } /** * 设置最小缩放比列,最大值和图片大小相等 */ private void setMinZoom() { minScaleR = Math.min( (float) mDisplyMetrcs.widthPixels / (float) mBitmap.getWidth(), (float) mDisplyMetrcs.heightPixels / (float) mBitmap.getHeight()); if (minScaleR < 1.0) matrix.postScale(minScaleR, minScaleR); } private void setCenter() { this.setCenter(true, true); } private void setCenter(boolean horizontal, boolean vertical) { Matrix mMatrix = new Matrix(); mMatrix.set(matrix); RectF mRectF = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight()); mMatrix.mapRect(mRectF); float height = mRectF.height(); float width = mRectF.width(); float deltaX = 0, deltaY = 0; if (vertical) { // 图片小于屏幕大小,则居中显示。大于屏幕,上方留空则往上移,下方留空则往下移 int screenHeight = mDisplyMetrcs.heightPixels; if (height < screenHeight) deltaY = (screenHeight - height) / 2 - mRectF.top; else if (mRectF.top > 0) deltaY = -mRectF.top; else if (mRectF.bottom < screenHeight) deltaY = mImageView.getHeight() - mRectF.bottom; } if (horizontal) { int screenWidth = mDisplyMetrcs.widthPixels; if (width < screenWidth) deltaX = (screenWidth - width) / 2 - mRectF.left; else if (mRectF.left > 0) deltaX = -mRectF.left; else if (mRectF.right < screenWidth) deltaX = screenWidth - mRectF.right; } matrix.postTranslate(deltaX, deltaY); } /** * 两点的距离 * * @param event * @return */ 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); } /** * 两点的中点 * * @param point * @param event */ 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); } }
布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/mImageView" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
好了,到此结束。
程序源码下载
本程序是一个简单的Demo,所以只支持多点触摸进行缩放,测试需在真机中运行,所以,在这里向用模拟器测试的同学表示遗憾。
好了,至此,由于我也是在模拟器中运行,所以,缩放效果无法展示,请大家自测:
相关文章推荐
- android Matrix实现图片随意放大缩小或拖动
- 简单的利用scrollerview实现的图片的放大缩小,以及中心点的固定
- Android开发--Matrix(一)--实现图片的动态放大缩小
- android 图片随意的放大缩小拖动利用Matrix
- Android开发--Matrix(一)--实现图片的动态放大缩小
- andriod 利用WebView实现 图片放大缩小以及移动[转]
- Android自定义ImageView(二)——实现双击放大与缩小图片
- Android 自定义View 之利用ViewPager 实现画廊效果(滑动放大缩小)
- Qt+OpenGL实现正方体旋转平移放大缩小,以及六个面贴不同图片
- Android实现图片放大缩小
- ExtJs 完美实现图片在Window窗口中通过鼠标滚轮放大缩小以及点击拖拽
- android实现对图片的放大缩小旋转等操作
- Android 利用Matrix实现图片的缩放查看
- android图片缩小和放大Matrix
- Android------实现图片双击放大,缩小,左右滑动的多种方式
- 我的Android进阶之旅------>android Matrix图片随意的放大缩小,拖动
- Android------实现图片双击放大,缩小,左右滑动的多种方式
- 利用jQuery插件imgAreaSelect实现图片上传裁剪(放大缩小)
- Android 图片拖动以及放大缩小
- Android App中实现可以双击放大和缩小图片功能的实例