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類 java

DisplayMetrics dm = getApplicationContext().getResources()
				.getDisplayMetrics();
		screenWidth = dm.widthPixels;
		screenHeight = dm.heightPixels;
相關文章
相關標籤/搜索