<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" > <ImageView
android:id="@+id/imag"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:scaleType="matrix" >
</ImageView> </FrameLayout>

      Android 图片的浏览、缩放、拖动和自动居中 

转载地址:http://www.cnblogs.com/dwinter/archive/2012/01/12/2321082.html

  • Touch.java
/**
* 图片浏览、缩放、拖动、自动居中
*/
public class Touch extends Activity implements OnTouchListener { Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
DisplayMetrics dm;
ImageView imgView;
Bitmap bitmap; float minScaleR;// 最小缩放比例
static final float MAX_SCALE = 4f;// 最大缩放比例 static final int NONE = 0;// 初始状态
static final int DRAG = 1;// 拖动
static final int ZOOM = 2;// 缩放
int mode = NONE; PointF prev = new PointF();
PointF mid = new PointF();
float dist = 1f; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scale);
imgView = (ImageView) findViewById(R.id.imag);// 获取控件
bitmap = BitmapFactory.decodeResource(getResources(), this.getIntent()
.getExtras().getInt("IMG"));// 获取图片资源
imgView.setImageBitmap(bitmap);// 填充控件
imgView.setOnTouchListener(this);// 设置触屏监听
dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);// 获取分辨率
minZoom();
center();
imgView.setImageMatrix(matrix);
} /**
* 触屏监听
*/
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;
}
imgView.setImageMatrix(matrix);
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);
}
}
center();
} /**
* 最小缩放比例,最大为100%
*/
private void minZoom() {
minScaleR = Math.min(
(float) dm.widthPixels / (float) bitmap.getWidth(),
(float) dm.heightPixels / (float) bitmap.getHeight());
if (minScaleR < 1.0) {
matrix.postScale(minScaleR, minScaleR);
}
} private void center() {
center(true, true);
} /**
* 横向、纵向居中
*/
protected void center(boolean horizontal, boolean vertical) { Matrix m = new Matrix();
m.set(matrix);
RectF rect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
m.mapRect(rect); float height = rect.height();
float width = rect.width(); float deltaX = 0, deltaY = 0; if (vertical) {
// 图片小于屏幕大小,则居中显示。大于屏幕,上方留空则往上移,下方留空则往下移
int screenHeight = dm.heightPixels;
if (height < screenHeight) {
deltaY = (screenHeight - height) / 2 - rect.top;
} else if (rect.top > 0) {
deltaY = -rect.top;
} else if (rect.bottom < screenHeight) {
deltaY = imgView.getHeight() - rect.bottom;
}
} if (horizontal) {
int screenWidth = dm.widthPixels;
if (width < screenWidth) {
deltaX = (screenWidth - width) / 2 - rect.left;
} else if (rect.left > 0) {
deltaX = -rect.left;
} else if (rect.right < screenWidth) {
deltaX = screenWidth - rect.right;
}
}
matrix.postTranslate(deltaX, deltaY);
} /**
* 两点的距离
*/
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);
} /**
* 两点的中点
*/
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);
}
}
  • scale.xml

android Matrix图片随意的放大缩小,拖动

转载地址:http://www.bdqn.cn/news/201304/8794.shtml

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>
 

android图片缩放平移的更多相关文章

  1. Android 图片的平移和镜面和倒影效果

    在前面的文章中陆续介绍了图片的旋转与缩放,本文继续介绍关于图片的操作 图片的平移 使用下面的代码将图水平竖直方向平移10个像素 matrix.setTranslate(10, 10); 可以看到图片不 ...

  2. C#图片缩放平移 —— 从功能分析到编码实现

    序 一直都是在看别人的博客,查到想要的,看完后把页面一关就万事大吉了,没啥感觉:直到后来遇到了同样的问题,总想不起来咋弄,关键是还查不到以前看过的,郁闷!现在想想,还是“好记性不如烂笔头”啊,自己弄过 ...

  3. Android图片缩放方法

    安卓开发中应用到图片的处理时候,我们通常会怎么缩放操作呢,来看下面的两种做法: 方法1:按固定比例进行缩放 在开发一些软件,如新闻客户端,很多时候要显示图片的缩略图,由于手机屏幕限制,一般情况下,我们 ...

  4. android 图片的平移,缩放和旋转

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...

  5. Delphi XE5 for android 图片缩放和拖动处理

    首先,需要分辨手势的类型. 有两种类型的手势: 一是标准手势(Standard Gestures): 在Windows,android上,标准手势都是用一个手指. 在Mac OS X and iOS上 ...

  6. Android 图片缩放

    以下演示将一个ImageView的高度设置为两倍: 布局文件main.xml <?xml version="1.0" encoding="utf-8"?& ...

  7. Android图片缩放 指定尺寸

    //使用Bitmap加Matrix来缩放     public static Drawable resizeImage(Bitmap bitmap, int w, int h)     {       ...

  8. android 图片缩放抗锯齿

    之前用的时候只设置了antialias属性,其实要设置两个flag才行 paint.setFlags(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG); ...

  9. Android实现支持缩放平移图片

    本文主要用到了以下知识点 Matrix GestureDetector 能够捕捉到长按.双击 ScaleGestureDetector 用于检测缩放的手势 自由的缩放 需求:当图片加载时,将图片在屏幕 ...

随机推荐

  1. LTE协议

    开启通信不归路的第一炮!----LTE整体框架和协议架构概述 (2015-03-09 09:07:04) 转载▼   分类: 通信那些事儿 听说“态度.决心.毅力和细心”一定可以成就一个人!而我们也总 ...

  2. SpringMVC之七:SpringMVC中使用Interceptor拦截器

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...

  3. Python 同ip网站查询(制作网站接口)

    老师专门打电话回来说不让玩电脑~~   呵呵.  LOL把被人坑死了. 五排果然不适合我. 去翻了下曾经的Python项目. 在爬虫文件夹下面找到了这个. 我也就厚脸皮的什么都不改就放上来了: #co ...

  4. linux下使用c判断文件夹是否为空的小程序

    自己写了一个 判断文件夹是否为空的小代码 //文件夹操作相关的函数的帮助$: man 3 readdir #include <stdio.h> #include <sys/types ...

  5. Debian系统下的ftp服务搭建

    安装vsftpd服务 $ sudo apt install vsftpd 配置参数 命令输入 $ vim /etc/vsftpd.conf 使用如下配置 # Example config file / ...

  6. 无监督学习:Deep Auto-encoder(深度自动编码器)

    一 Auto-encoder NN Encoder & NN Decoder 要一起训练. 二 Starting from PCA 三 Deep Auto-encoder PCA&De ...

  7. Windows CreateEvent,SetEvent,WaitForSingleObject的用法

    http://blog.pfan.cn/embed/19089.html WaitForSingleObject的用法 DWORD WaitForSingleObject(   HANDLE hHan ...

  8. codeforces 352D - Jeff and Furik【期望dp】

    首先恋人操作过一轮之后逆序对不会变多,所以设f[i]为把i个逆序对消掉的期望次数,f[i]=0.5f[i-2]+0.5f[i]+2,化简然后递推即可 #include<iostream> ...

  9. Android实现点击两次返回退出APP

    Android实现点击两次退出APP 这两天在做一个项目碰到这么个问题,需要主界面点击两次直接退出整个APP而不是返回上一个界面,查找了网上的资料,整合和修改了一下写了这篇博客. 这里我主要以我的项目 ...

  10. Spring - SpringIOC容器详解

    一.什么是Spring IOC: Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想. 在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是 ...