android Matrix实现图片随意放大缩小或拖动
程序员文章站
2023-12-13 21:23:28
本文实例为大家分享了android matrix图片随意放大缩小和拖动的具体代码,供大家参考,具体内容如下
step1:新建一个项目dragandzoom,并准备一张照片...
本文实例为大家分享了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; } }
查看一下运行的效果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。