android手势缩放

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.net.URL;
import java.util.HashMap;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;


public class ImageUtil {
	private static HashMap<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();

	/**
	 * JPG图片缓存
	 * 
	 * @param imagePath
	 * @param bitmap
	 * @throws IOException
	 */
	public static void saveImageJpeg(String imagePath, Bitmap bitmap)
			throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
		byte[] b = bos.toByteArray();
		saveImage(imagePath, b);
		bos.flush();
		bos.close();
	}

	/**
	 * PNG图片缓存
	 * 
	 * @param imagePath
	 * @param buffer
	 * @throws IOException
	 */

	public static void saveImagePng(String imagePath, Bitmap bitmap)
			throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
		byte[] b = bos.toByteArray();
		saveImage(imagePath, b);
		bos.flush();
		bos.close();
	}

	/**
	 * 缓存图片
	 * 
	 * @param imagePath
	 * @param buffer
	 * @throws IOException
	 */
	public static void saveImage(String imagePath, byte[] buffer)
			throws IOException {
		File f = new File(imagePath);
		if (f.exists()) {
			return;
		} else {
			File parentFile = f.getParentFile();
			if (!parentFile.exists()) {
				parentFile.mkdirs();
			}
			f.createNewFile();
			FileOutputStream fos = new FileOutputStream(imagePath);
			fos.write(buffer);
			fos.flush();
			fos.close();
		}
	}

	/**
	 * 从本地获取图片
	 * 
	 * @param imagePath
	 * @return Bitmap
	 */
	public static Bitmap getImageFromLocal(String imagePath) {
		File file = new File(imagePath);
		if (file.exists()) {
			Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
			file.setLastModified(System.currentTimeMillis());
			return bitmap;
		}
		return null;
	}

	/**
	 * 从网络获取图片并缓存
	 * 
	 * @return Bitmap
	 * @throws IOException
	 */
	public Bitmap loadImage(final String imagePath, final String imgUrl,
			final boolean isbusy, final ImageCallback callback) {
		callback.onStart();
		Bitmap bitmap = null;
		if (imageCache.containsKey(imgUrl)) {
			SoftReference<Bitmap> softReference = imageCache.get(imgUrl);
			bitmap = softReference.get();
			if (bitmap != null) {
				// System.out.println("从软应用获取图片");
				return bitmap;
			}
		}
		// if(!isbusy){
		// 从本地获取图片
		bitmap = getImageFromLocal(imagePath);
		// System.out.println("从本地获取图片");
		// }
		if (bitmap != null) {
			imageCache.put(imgUrl, new SoftReference<Bitmap>(bitmap));
			// System.out.println("向软应用储存图片");
			return bitmap;
		} else {// 从网络获取图片
			final Handler handler = new Handler() {
				@Override
				public void handleMessage(Message msg) {
					if (msg.obj != null) {
						Bitmap bitmap = (Bitmap) msg.obj;
						imageCache.put(imgUrl,
								new SoftReference<Bitmap>(bitmap));
						if (android.os.Environment.getExternalStorageState()
								.equals(android.os.Environment.MEDIA_MOUNTED)) {
							try {
								if (imgUrl.endsWith(".png")) {
									saveImagePng(imagePath, bitmap);
								} else if (imgUrl.endsWith(".jpg")) {
									saveImageJpeg(imagePath, bitmap);
								}
								// System.out.println("向SD卡获取图片");

							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						callback.loadImage(bitmap, imagePath);

					}
				}
			};

			Runnable runnable = new Runnable() {
				@Override
				public void run() {
					try {

						Bitmap bitmap = null;
						if (imgUrl != null && !"".equals(imgUrl)) {
							byte[] b = getUrlBytes(imgUrl);
							/*
							 * BitmapFactory.Options opts = new
							 * BitmapFactory.Options(); opts.inJustDecodeBounds
							 * = true;
							 * BitmapFactory.decodeStream(getUrlInputStream
							 * (imgUrl), null, opts);
							 * 
							 * opts.inSampleSize = computeSampleSize(opts, -1,
							 * 128*128); opts.inJustDecodeBounds = false; try {
							 * bitmap =
							 * BitmapFactory.decodeStream(getUrlInputStream
							 * (imgUrl), null, opts); } catch (OutOfMemoryError
							 * err) { }
							 */
							bitmap = BitmapFactory.decodeByteArray(b, 0,
									b.length);
							// Bitmap bitmap = BitmapFactory.decodeStream(bis);
						}
						Message msg = handler.obtainMessage();
						msg.obj = bitmap;
						handler.sendMessage(msg);
					} catch (Exception e) {
						e.printStackTrace();
						callback.onFailed();
					}
				}
			};
			ThreadPoolManager.getInstance().addTask(runnable);
		}
		return bitmap;
	}

	public static int computeSampleSize(BitmapFactory.Options options,
			int minSideLength, int maxNumOfPixels) {
		int initialSize = computeInitialSampleSize(options, minSideLength,
				maxNumOfPixels);

		int roundedSize;
		if (initialSize <= 8) {
			roundedSize = 1;
			while (roundedSize < initialSize) {
				roundedSize <<= 1;
			}
		} else {
			roundedSize = (initialSize + 7) / 8 * 8;
		}

		return roundedSize;
	}

	private static int computeInitialSampleSize(BitmapFactory.Options options,
			int minSideLength, int maxNumOfPixels) {
		double w = options.outWidth;
		double h = options.outHeight;

		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
				.sqrt(w * h / maxNumOfPixels));
		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(
				Math.floor(w / minSideLength), Math.floor(h / minSideLength));

		if (upperBound < lowerBound) {
			// return the larger one when there is no overlapping zone.
			return lowerBound;
		}

		if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
			return 1;
		} else if (minSideLength == -1) {
			return lowerBound;
		} else {
			return upperBound;
		}
	}

	/**
	 * 获取指定路径的Byte[]数据-通用
	 * 
	 * @param urlpath
	 * @return byte[]
	 * @throws Exception
	 */
	public static byte[] getUrlBytes(String urlpath) throws Exception {
		InputStream in_s = getUrlInputStream(urlpath);
		return readStream(in_s);
	}

	/**
	 * 获取指定路径的InputStream数据-通用
	 * 
	 * @param urlpath
	 * @return byte[]
	 * @throws Exception
	 */
	public static InputStream getUrlInputStream(String urlpath)
			throws Exception {
		URL url = new URL(urlpath);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		// conn.setRequestMethod("GET");
		conn.setRequestMethod("GET");
		conn.setConnectTimeout(15*1000);// 10秒超时
		int responseCode = conn.getResponseCode();
		Log.i("image", responseCode + "");
		System.out.println(responseCode + "");
		if (responseCode == HttpURLConnection.HTTP_OK) {// 返回码200等于返回成功
			InputStream inputStream = conn.getInputStream();
			return inputStream;
		}
		return null;
	}

	/**
	 * 从InputStream中读取数据-通用
	 * 
	 * @param inStream
	 * @return byte[]
	 * @throws Exception
	 */
	public static byte[] readStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outstream = new ByteArrayOutputStream();
		byte[] buffer = new byte[128];
		int len = -1;
		while ((len = inStream.read(buffer)) != -1) {
			outstream.write(buffer, 0, len);
		}
		outstream.close();
		inStream.close();
		return outstream.toByteArray();
	}

	/**
	 * 获取缓存路径
	 * 
	 * @return sd卡路径
	 */
	public static String getCacheImgPath() {
		return Environment.getExternalStorageDirectory().getPath()
				+ "/pjchihuo/cache/";
	}

	/**
	 * 类功能描述:给网络上获取的图片设置的回调
	 * 
	 * @version 1.0 </p> 修改时间:</br> 修改备注:</br>
	 */
	public interface ImageCallback {
		public void onStart();
		public void loadImage(Bitmap bitmap, String imagePath);
		public void onFailed();
	}

}
import net.tsz.afinal.FinalBitmap;
import net.tsz.afinal.bitmap.core.BitmapDisplayConfig;

import com.pjchihuo.utils.CommonUtil;
import com.pjchihuo.utils.Constant;
import com.pjchihuo.utils.ImageUtil;
import com.pjchihuo.utils.ImageUtil.ImageCallback;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnKeyListener;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.FloatMath;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class BigImageActivity extends Activity implements OnTouchListener{
	Matrix matrix = new Matrix();
	Matrix savedMatrix = new Matrix();
	String picUrl;
	ImageView imgView;
	private TextView closeTv;
	Bitmap mainBitmap;
	Handler handler=new Handler();

	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;


	protected PanApplication app;
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		app = ((PanApplication) getApplication());
		app.addActvity(this);
		loadViewLayout();
		findViewById();
		processLogic();
		setListener();
	}

	/**
	 * 触屏监听
	 */
	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) app.screenWidth / (float) mainBitmap.getWidth(),
				(float) app.screenHeight / (float) mainBitmap.getHeight());
		if (minScaleR < 1.0) {
			matrix.postScale(minScaleR, minScaleR);
		}
	}

	private void center() {
		if(mainBitmap!=null){
			center(true, true);
		}
		}
		

	/**
	 * 横向、纵向居中
	 */
	protected void center(boolean horizontal, boolean vertical) {

		Matrix m = new Matrix();
		m.set(matrix);
		RectF rect = new RectF(0, 0, mainBitmap.getWidth(), mainBitmap.getHeight());
		m.mapRect(rect);

		float height = rect.height();
		float width = rect.width();

		float deltaX = 0, deltaY = 0;

		if (vertical) {
			// 图片小于屏幕大小,则居中显示。大于屏幕,上方留空则往上移,下方留空则往下移
			int screenHeight = app.screenHeight;
			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 = app.screenWidth;
			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);
	}

	protected void findViewById() {
		imgView = (ImageView) this.findViewById(R.id.iv_zoome_pic);

	}

	protected void loadViewLayout() {
		setContentView(R.layout.image_big);

	}
	/**
	 * 关闭提示框
	 */
	protected void closeProgressDialog() {
		if (this.progressDialog != null)
			this.progressDialog.dismiss();
	}
	protected void processLogic() {
		picUrl = getIntent().getStringExtra("imageUrl");
//		BitmapDisplayConfig config = new BitmapDisplayConfig()
//		config.
//		FinalBitmap.create(this,ImageUtil.getCacheImgPath()).display();
		
		String imagePath = ImageUtil.getCacheImgPath().concat(
				CommonUtil.md5(Constant.URL + "/" + picUrl));
		ImageUtil util = new ImageUtil();
		Bitmap bitmap = util.loadImage(imagePath, Constant.URL + "/" + picUrl,
				false, new ImageCallback() {
					@Override
					public void loadImage(Bitmap bitmap, String imagePath) {
						if(bitmap!=null){
							mainBitmap = bitmap;
							imgView.setImageBitmap(mainBitmap);
							minZoom();
							center();
							imgView.setImageMatrix(matrix);
							closeProgressDialog();
						}
						
					}

					@Override
					public void onStart() {
						showProgressDialog(getResources().getString(R.string.xlistview_body_loading));
						
					}

					@Override
					public void onFailed() {
						closeProgressDialog();
						handler.post(new Runnable() {
							
							@Override
							public void run() {
								Toast.makeText(BigImageActivity.this,"加载图片失败,请稍后重试" , Toast.LENGTH_SHORT).show();
							}
						});
						
						
					}


				});
		if(bitmap!=null){
			mainBitmap = bitmap;
			imgView.setImageBitmap(mainBitmap);
			minZoom();
			center();
			imgView.setImageMatrix(matrix);
			closeProgressDialog();
		}

	}
	/**
	 * 显示正在加载提示框
	 */
	protected ProgressDialog progressDialog;
	protected void showProgressDialog(String message) {
		if ((!isFinishing()) && (this.progressDialog == null)) {
			this.progressDialog = new ProgressDialog(this);
		}
		progressDialog.setOnKeyListener(new OnKeyListener() {

			@Override
			public boolean onKey(DialogInterface dialog, int keyCode,
					KeyEvent event) {
				if (keyCode == event.KEYCODE_BACK) {
//					if (httpManager != null) {
//						httpManager.cancelHttpRequest();
//					}
				}
				return false;
			}
		});
//		progressDialog.setCancelable(false);
		// this.progressDialog.setTitle(getString(R.string.loadTitle));
		this.progressDialog.setMessage(message);
		this.progressDialog.show();
	}
	protected void setListener() {
		imgView.setOnTouchListener(this);// 设置触屏监听

	}

}

新建application类

DisplayMetrics dm = getApplicationContext().getResources()
				.getDisplayMetrics();
		screenWidth = dm.widthPixels;
		screenHeight = dm.heightPixels;

转载于:https://my.oschina.net/u/861587/blog/147511

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值