当前位置: 移动技术网 > 移动技术>移动开发>Android > android Matrix实现图片随意放大缩小或拖动

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

本文实例为大家分享了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; 
 } 
 
} 

查看一下运行的效果

    

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网