android Matrix实现图片随意放大缩小或拖动

本文实例为大家分享了android Matrix图片随意放大缩小和拖动的具体代码,供大家参考,具体内容如下

step1:新建一个项目DragAndZoom,并准备一张照片放在res/drawable-hdpi目录下,如下图所示:

step2: 设置应用的UI界面,在main.xml中设置:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 >
<ImageView
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:src="@drawable/wall"
 android:id="@+id/imageView"
 android:scaleType="matrix"
 /> <!-- 指定为matrix类型 -->
</LinearLayout>

step3:MainActivity.java中实现具体的需求

package cn.roco.drag; 

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

public class MainActivity extends Activity { 

 private ImageView imageView; 

 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main); 

 imageView = (ImageView) this.findViewById(R.id.imageView);
 imageView.setOnTouchListener(new TouchListener());
 } 

 private final class TouchListener implements OnTouchListener { 

 /** 记录是拖拉照片模式还是放大缩小照片模式 */
 private int mode = 0;// 初始状态
 /** 拖拉照片模式 */
 private static final int MODE_DRAG = 1;
 /** 放大缩小照片模式 */
 private static final int MODE_ZOOM = 2; 

 /** 用于记录开始时候的坐标位置 */
 private PointF startPoint = new PointF();
 /** 用于记录拖拉图片移动的坐标位置 */
 private Matrix matrix = new Matrix();
 /** 用于记录图片要进行拖拉时候的坐标位置 */
 private Matrix currentMatrix = new Matrix(); 

 /** 两个手指的开始距离 */
 private float startDis;
 /** 两个手指的中间点 */
 private PointF midPoint; 

 @Override
 public boolean onTouch(View v, MotionEvent event) {
  /** 通过与运算保留最后八位 MotionEvent.ACTION_MASK = 255 */
  switch (event.getAction() & MotionEvent.ACTION_MASK) {
  // 手指压下屏幕
  case MotionEvent.ACTION_DOWN:
  mode = MODE_DRAG;
  // 记录ImageView当前的移动位置
  currentMatrix.set(imageView.getImageMatrix());
  startPoint.set(event.getX(), event.getY());
  break;
  // 手指在屏幕上移动,改事件会被不断触发
  case MotionEvent.ACTION_MOVE:
  // 拖拉图片
  if (mode == MODE_DRAG) {
   float dx = event.getX() - startPoint.x; // 得到x轴的移动距离
   float dy = event.getY() - startPoint.y; // 得到x轴的移动距离
   // 在没有移动之前的位置上进行移动
   matrix.set(currentMatrix);
   matrix.postTranslate(dx, dy);
  }
  // 放大缩小图片
  else if (mode == MODE_ZOOM) {
   float endDis = distance(event);// 结束距离
   if (endDis > 10f) { // 两个手指并拢在一起的时候像素大于10
   float scale = endDis / startDis;// 得到缩放倍数
   matrix.set(currentMatrix);
   matrix.postScale(scale, scale,midPoint.x,midPoint.y);
   }
  }
  break;
  // 手指离开屏幕
  case MotionEvent.ACTION_UP:
  // 当触点离开屏幕,但是屏幕上还有触点(手指)
  case MotionEvent.ACTION_POINTER_UP:
  mode = 0;
  break;
  // 当屏幕上已经有触点(手指),再有一个触点压下屏幕
  case MotionEvent.ACTION_POINTER_DOWN:
  mode = MODE_ZOOM;
  /** 计算两个手指间的距离 */
  startDis = distance(event);
  /** 计算两个手指间的中间点 */
  if (startDis > 10f) { // 两个手指并拢在一起的时候像素大于10
   midPoint = mid(event);
   //记录当前ImageView的缩放倍数
   currentMatrix.set(imageView.getImageMatrix());
  }
  break;
  }
  imageView.setImageMatrix(matrix);
  return true;
 } 

 /** 计算两个手指间的距离 */
 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);
 } 

 } 

}

step4:AndroidMainfest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="cn.roco.drag"
 android:versionCode="1"
 android:versionName="1.0">
 <uses-sdk android:minSdkVersion="8" /> 

 <application android:icon="@drawable/icon" android:label="@string/app_name">
 <activity android:name=".MainActivity"
   android:label="@string/app_name">
  <intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
 </activity> 

 </application>
</manifest> 

step5:具体的效果图

上面两个是图片拖拽的效果,而图片的缩放效果要在真机中才能够看得到,请读者自己在真机环境中测试。

附注:具体的程序源码在:下载程序源码

其实通过通过手势也可以缩放图片  左--->右 放大 右 --->左 缩小 速度越快,缩放比例越大

zoom.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 >
<ImageView
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:src="@drawable/wall"
 android:id="@+id/show"
 android:scaleType="matrix"
 /> <!-- 指定为matrix类型 -->
</LinearLayout>

GestureZoom.java

package cn.roco.gesture; 

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.widget.ImageView; 

/**
 * 通过手势 缩放图片 左--->右 放大 右 --->左 缩小 速度越快,缩放比例越大
 */
public class GestureZoom extends Activity implements OnGestureListener {
 // 定义手势检测器实例
 GestureDetector detector;
 ImageView imageView;
 // 初始化图片资源
 Bitmap bitmap;
 // 定义图片的高和宽
 int width, height;
 // 记录当前的缩放比
 float currentScale = 1;
 // 控制图片缩放的Matrix对象
 Matrix matrix; 

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.zoom);
 // 创建手势检测器
 detector = new GestureDetector(this);
 imageView = (ImageView) findViewById(R.id.show);
 matrix = new Matrix();
 // 获取被缩放的源图片
 bitmap = BitmapFactory.decodeResource(this.getResources(),
  R.drawable.wall);
 // 获得位图的宽
 width = bitmap.getWidth();
 // 获得位图的高
 height = bitmap.getHeight();
 // 设置 ImageView初始化显示的图片
 imageView.setImageBitmap(BitmapFactory.decodeResource(
  this.getResources(), R.drawable.wall));
 } 

 @Override
 public boolean onTouchEvent(MotionEvent event) {
 // 将该Activity上的触碰时间交个 GestureDetector处理
 return detector.onTouchEvent(event);
 } 

 @Override
 public boolean onDown(MotionEvent e) {
 // TODO Auto-generated method stub
 return false;
 } 

 @Override
 public void onShowPress(MotionEvent e) {
 // TODO Auto-generated method stub 

 } 

 @Override
 public boolean onSingleTapUp(MotionEvent e) {
 return false;
 } 

 @Override
 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
  float distanceY) {
 return false;
 } 

 @Override
 public void onLongPress(MotionEvent e) { 

 } 

 @Override
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  float velocityY) {
 velocityX = velocityX > 4000 ? 4000 : velocityX;
 velocityY = velocityY < -4000 ? -4000 : velocityY;
 // 感觉手势的速度来计算缩放比,如果 velocityX>0,放大图像,否则缩小图像
 currentScale += currentScale * velocityX / 4000.0f;
 // 保证 currentScale 不会等于0
 currentScale = currentScale > 0.01 ? currentScale : 0.01f;
 // 重置 Matrix
 matrix.setScale(currentScale, currentScale, 160, 200);
 BitmapDrawable tmp = (BitmapDrawable) imageView.getDrawable();
 // 如果图片还未回收,先强制收回该图片
 if (!tmp.getBitmap().isRecycled()) {
  tmp.getBitmap().recycle();
 }
 // 根据原始位图和 Matrix创建新图片
 Bitmap bitmap2 = Bitmap.createBitmap(bitmap, 0, 0, width, height,
  matrix, true);
 //显示新的位图
 imageView.setImageBitmap(bitmap2);
 return true;
 } 

}

查看一下运行的效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 深入理解Android Matrix理论与使用的详解

    以前在线性代数中学习了矩阵,对矩阵的基本运算有一些了解,前段时间在使用GDI+的时候再次学习如何使用矩阵来变化图像,看了之后在这里总结说明.首先大家看看下面这个3 x 3的矩阵,这个矩阵被分割成4部分.为什么分割成4部分,在后面详细说明. 首先给大家举个简单的例子:现设点P0(x0, y0)进行平移后,移到P(x,y),其中x方向的平移量为△x,y方向的平移量为△y,那么,点P(x,y)的坐标为:x = x0  + △x y = y0  + △y采用矩阵表达上述如下:  上述也类似与图像的平移,

  • Android中使用Matrix控制图形变换和制作倒影效果的方法

    最近在使用Matrix进行绘图的操作.对Matrix的一些方法有了一些更深的体会,记下来,以便日后复习. Matrix常用的方法: 一.变换方法: Matrix提供了translate(平移).rotate(旋转).scale(缩放).skew(倾斜)四种操作,这四种操作的内部实现过程都是通过matrix.setValues(-)来设置矩阵的值来达到变换图片的效果. Matrix的每种操作都有set.pre.post三种操作,set是清空队列再添加,pre是在队列最前面插入,post是在队列最后

  • Android中Matrix用法实例分析

    本文实例讲述了Android中Matrix用法.分享给大家供大家参考,具体如下: Matrix ,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放.平移.旋转等操作. 首先介绍一下矩阵运算.加法和减法就不用说了,对应位相加就好.图像处理,主要用到的是乘法 .下面是一个乘法的公式: 在 Android 里面, Matrix 由 9 个 float 值构成,是一个 3*3 的矩阵.如下图: 解释一下,上面的sinX 和cosX ,表示旋转角度的cos 值和sin值,注意,旋转角度

  • Android Matrix源码详解

    Matrix的数学原理 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类.Android中的Matrix是一个3 x 3的矩阵,其内容如下: Matrix的对图像的处理可分为四类基本变换: Translate           平移变换 Rotate                旋转变换 Scale                  缩放变换 Skew                  错切变换 从字面上理解,矩阵中的MSCALE用于处理缩放变换,MSK

  • android.graphics.Matrix类用法分析

    本文实例讲述了android.graphics.Matrix类用法.分享给大家供大家参考,具体如下: Matrix类包含了一个3x3的矩阵用来改变坐标,它没有一个构造器来初始化它里边的内容,所以创建实例后需要调用reset()方法生成一个标准matrix,或者调用set..一类的函数,比如setTranslate, setRotate,,该函数将会决定matrix如何来改变坐标.SDK里边没有讲述Matrix的3x3矩阵是如何改变点的坐标值的,但是我在代码里边通过打印那9个点的值时,大致可以得到

  • Android中利用matrix 控制图片的旋转、缩放、移动

    本文主要讲解利用android中Matrix控制图形的旋转缩放移动,具体参见一下代码: 复制代码 代码如下: /**  * 使用矩阵控制图片移动.缩放.旋转  */  public class CommonImgEffectView extends View { private Context context ;      private Bitmap mainBmp , controlBmp ;      private int mainBmpWidth , mainBmpHeight , c

  • Android 矩阵ColorMatrix

    中文名:坐标矩阵 高等数学里有介绍,在图像处理方面,主要是用于平面的缩放.平移.旋转等操作. 在Android里面,Matrix由9个float值构成,是一个3*3的矩阵.最好记住.如下图 各个字段的含义: 上面的sinX和cosX,表示旋转角度的cos值和sin值,注意,旋转角度是按顺时针方向计算的. translateX和translateY表示x和y的平移量.scale是缩放的比例,1是不变,2是表示缩放1/2,这样子. 如何使用 set,pre,post方法 Matrix调用一系列set

  • Android变形(Transform)之Matrix用法

    引言 最近在研究Android的变形,Android的2D变形(包括缩放,扭曲,平移,旋转等)可以通过Matrix来实现,3D变形可以通过Camera来实现.接下来就将我这俩天研究的东西和大家分享下,先来看看Matrix的用法. 效果图 变形以后 Matrix矩阵 坐标变换矩阵,即一个3*3的矩阵,用来对图形进行坐标变换. 图1.1  A为坐标矩阵,C为原始矩阵,R是A和C矩阵相乘记过,那么可以知道:(矩阵知识,大学没学好的伤不起啊) x' = a*x + b*y + c y' = d*x +

  • 详谈Android中Matrix的set、pre、post的区别

    说set.pre.post的区别之前,先说说Matrix. Matrix包含一个3 X 3的矩阵,专门用于图像变换匹配. Matrix提供了四种操作: •translate(平移) •rotate(旋转) •scale(缩放) •skew(倾斜) 也就是说这4种操作都是对这个3 X 3的矩阵设值来达到变换的效果. Matrix没有结构体,它必须被初始化,通过reset或set方法. OK,Matrix介绍完了,我们来看看set.pre.post的区别. pre是在队列最前面插入,post是在队列

  • Android使用Matrix旋转图片模拟碟片加载过程

    今天实现了一个模拟碟片加载过程的小demo,在此展示一下.由于在公司,不好截取动态图片,因此就在这截取两张静态图片看看效果先. 下面简单的将代码列出来. setp1.准备两张用于旋转的图片,如下:loading_disc.png是第一张图片,loading_light.png是第二张图片.      step2.自定义一个View,用来控制这两个图片的旋转.com.oyp.loadingdisk.LoadingDiscView.java package com.oyp.loadingdisk;

  • android高仿小米时钟(使用Camera和Matrix实现3D效果)

    继续练习自定义View..毕竟熟才能生巧.一直觉得小米的时钟很精美,那这次就搞它~这次除了练习自定义View,还涉及到使用Camera和Matrix实现3D效果. 一个这样的效果,在绘制的时候最好选择一个方向一步一步的绘制,这里我选择由外到内.由深到浅的方向来绘制,代码步骤如下: 1.首先老一套~新建attrs.xml文件,编写自定义属性如时钟背景色.亮色(用于分针.秒针.渐变终止色).暗色(圆弧.刻度线.时针.渐变起始色),新建MiClockView继承View,重写构造方法,获取自定义属性值

随机推荐