内容如题:

以前对于图片缩放时出现oom,也是束手无策。昨天看了 Android_Tutor对于图片处理的文章,今天就斗胆将这部分的内容演习下。

首先创建一个布局文件:用imageview控件加载图片

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <Button        android:id="@+id/show"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="@string/hello_world" />    <ImageView        android:id="@+id/imageview"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:scaleType="matrix"        android:src="@drawable/ic_launcher" /></LinearLayout>

其次:用公共类ImageCacheUtil对图片进行压缩处理:这样可以保证图片太大的时候不会出现oom

/** * @FILE:ImageCacheUtil.java * @AUTHOR:hui-ye * @DATE:2013-6-19 下午2:23:56 **/package com.view.imagecachedemo;import java.io.InputStream;import android.content.ContentResolver;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.BitmapFactory.Options;import android.net.Uri;/******************************************* *  * @CLASS:ImageCacheUtil * @DESCRIPTION:获得经过缩放处理的bitmap,以保证不会出现oom * @AUTHOR:hui-ye * @VERSION:v1.0 * @DATE:2013-6-19 下午2:23:56 *******************************************/public class ImageCacheUtil {/** * @description:获取bitmap * @author:hui-ye * @param path 图片文件的路径 * @param data图片的文件的数据 * @param context 上下文对象 * @param uri 资源 * @param target 模板宽或者高的大小 * @param width 是否是宽度 * @return: */public static Bitmap getResizedBitmap(String path, byte[] data,Context context, Uri uri, int target, boolean width)throws Exception {// android api// BitmapFactory.Options options = new BitmapFactory.Options();// options.inJustDecodeBounds = true;// BitmapFactory.decodeResource(getResources(), R.id.myimage, options);// int imageHeight = options.outHeight;// int imageWidth = options.outWidth;// String imageType = options.outMimeType;Bitmap bitmap = null;// 添加一个Options对象Options options = null;if (target > 0) {options = new Options();// 设置options的属性:inJustDecodeBounds=true的时候读取图片的时候,bitmap为null,将图片宽和高放到options中options.inJustDecodeBounds = true;// 获得图片(这样会将图片的宽和高放入到options中)decode(path, data, context, uri, options);// 获得压缩的比例int outWidth = options.outWidth;// 这样做宽和高就是相等了if (!width) {outWidth = Math.max(outWidth, options.outHeight);}// 计算压缩比例int ssize = sampleSize(outWidth, target);options.inSampleSize = ssize;// 设置inJustDecodeBounds = false,从新构建bitmapoptions.inJustDecodeBounds = false;bitmap = decode(path, data, context, uri, options);}return bitmap;}/** * @description:解析Bitmap的公用方法.注意各个方法的参数必须要有options * @author:hui-ye * @param path * @param data * @param context * @param uri * @param options * @return: */public static Bitmap decode(String path, byte[] data, Context context,Uri uri, BitmapFactory.Options options) throws Exception {Bitmap bitmap = null;if (path != null) {bitmap = BitmapFactory.decodeFile(path, options);} else if (data != null) {BitmapFactory.decodeByteArray(data, 0, data.length, options);} else if (uri != null) {// uri不为空的时候context也不要为空.:ContentResolver;Uri内容解析器ContentResolver resolver = context.getContentResolver();InputStream is;is = resolver.openInputStream(uri);bitmap = BitmapFactory.decodeStream(is, null, options);}return bitmap;}/*** @description:获取samplesize图片的压缩比例(这里就简单实现都是2的倍数啦.也就是說看width会是target的倍数)* @author:hui-ye* @param width* @param target* @return:*/private static int sampleSize(int width, int target) {int result = 1;for (int i = 0; i < 10; i++) {if (width < target * 2) {break;}width = width / 2;result = result * 2;}return result;}}

计算好了压缩比例,返回一个被压缩处理过的图片。

再次。打开相册,从中选择图片,进行压缩处理,将处理过的图片放到imageview中:

对于各个属性的说明:

/**  * 打开本地相册的requestcode.  */public static final int OPEN_PHOTO_REQUESTCODE = 0x1;/** * 图片的target大小. */private static final int target = 400;private ImageView image;/**    * matrix:这是一个图片的变化矩阵(提供记录图片位置、记录图片缩放比例、实现图片移动等 )  */private Matrix matrix;/**    * curmatrix:记录图片当前位置的变换矩阵   */private Matrix curmatrix;// 初始化模式参数private int mode = 0;// 无模式private static final int NONE = 0;// 拖拉模式private static final int DRAG = 1;// 缩放模式private static final int ZOOM = 2;/**    * startPoint:第一个点的坐标   */private PointF startPoint = new PointF();;/**    * startDistance:缩放前两个点之间的距离   */private float startDistance;/**    * endDistance:缩放后两个点之间的距离   */private float endDistance;/**    * middlePoint:两个点之间的中点   */private PointF middlePoint;/**    * ZOOM_THRESHOLD:当两点的  startDistance距离大于ZOOM_THRESHOLD的时候才缩放 */private static final float ZOOM_THRESHOLD = 10.0f;private Button show;


/** * @description:打开相册 * @author:hui-ye: */private void setupViews() {Intent intent = new Intent();intent.setAction(Intent.ACTION_PICK);intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/jpeg");startActivityForResult(intent, OPEN_PHOTO_REQUESTCODE);}


从相册中选择图片后,进行压缩处理,并将图片显示在imageview中

// 对startActivityForResult(intent,OPEN_PHOTO_REQUESTCODE );启动后的返回结果处理@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {switch (requestCode) {case OPEN_PHOTO_REQUESTCODE:if (resultCode == RESULT_OK) {Bitmap bitmap = null;// 将返回的数据构建成bitmaptry {bitmap = ImageCacheUtil.getResizedBitmap(null, null, this,data.getData(), target, false);} catch (Exception e) {e.printStackTrace();Toast.makeText(this, "生成图片失败", 1).show();}if (bitmap != null) {// 为imageview设置图片image.setImageBitmap(bitmap);}}break;default:break;}super.onActivityResult(requestCode, resultCode, data);}

最后处理图片的缩放:

// 这里对图片的缩放处理image.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction() & MotionEvent.ACTION_MASK) {// 取得第一个触控点的坐标case MotionEvent.ACTION_DOWN:// 设置当前的模式为拖拉模式mode = DRAG;// 记录图片当前的移动位置curmatrix.set(image.getImageMatrix());// 记录当前的坐标startPoint.set(event.getX(), event.getY());break;// 屏幕上已经有触控点了case MotionEvent.ACTION_POINTER_DOWN:// 如果是两点触控,则将mode设置为缩放模式mode = ZOOM;// 获取当前坐标和第一个坐标之间的距离startDistance = spacing(event);if (startDistance > ZOOM_THRESHOLD) {// 获取两点之间的中点middlePoint = getMiddlePoint(event);// 记录图片当前的缩放比例curmatrix.set(image.getImageMatrix());}break;// 判断触控点的移动(一个点移动还是多点移动 )case MotionEvent.ACTION_MOVE:// 一个点的移动为拖拉模式if (mode == DRAG) {// 获取x轴的移动距离float distanceX = event.getX() - startPoint.x;// 获取y轴的移动距离float distanceY = event.getY() - startPoint.y;// 设置 移动变换curmatrix.set(image.getImageMatrix());// 设置图片的移动matrix.postTranslate(distanceX, distanceY);} else if (mode == ZOOM) {// 结束距离endDistance = spacing(event);if (endDistance > ZOOM_THRESHOLD) {// 缩放比例float scale = endDistance / startDistance;matrix.set(curmatrix);matrix.postScale(scale, scale, middlePoint.x,middlePoint.y);}}case MotionEvent.ACTION_UP:// 当手指离开屏幕,但屏幕上仍有其他触点(手指)时触发该事件case MotionEvent.ACTION_POINTER_UP:mode = NONE;break;default:break;}image.setImageMatrix(matrix);return true;}});

// 计算移动距离private float spacing(MotionEvent event) {// event.getX(0)第一个点坐标,event.getX(1)为第二个点的坐标float x = event.getX(0) - event.getX(1);float y = event.getY(0) - event.getY(1);return FloatMath.sqrt(x * x + y * y);}/*** @description:获得两个点的中点坐标* @author:hui-ye* @param event* @return:*/public static PointF getMiddlePoint(MotionEvent event) {float x = (event.getX(0) + event.getX(1)) / 2;float y = (event.getY(0) + event.getY(1)) / 2;return new PointF(x, y);}

好了,介绍就到此为止,其他的希望大家去研究 android API http://developer.android.com/training/displaying-bitmaps/index.html

附件是完整的程序代码

作者:yehui18sui 发表于2013-6-20 15:59:58 原文链接 阅读:4 评论:0 查看评论

更多相关文章

  1. Android(安卓)图片的裁剪与相机调用
  2. android桌面悬浮窗显示录屏时间控制效果
  3. 获取Android手机上的图片和视频缩略图
  4. Android屏幕大小自适应
  5. Android的百度地图开发BaiduMapApiDemo
  6. Android下保存简单网页到本地(包括简单图片链接转换)
  7. Android高效加载大图,防止OOM,以及多图解决方案
  8. Android中实现自动轮播的框架(Banner)的介绍以及使用
  9. Android异步下载网络图片(其三)

随机推荐

  1. Android保存图片到系统相册
  2. Android(安卓)调试桥(adb)
  3. 复习TextView(查漏补缺)
  4. 移植rtmpdump(librtmp)到android
  5. Android深入浅出之Audio
  6. 【Android 应用开发】 Android APK 反编
  7. NCNN: 应用于手机上的卷积加速
  8. Android 电子罗盘 --指南针(方向传感器的
  9. [RK3288][Android6.0] 调试笔记 --- 替换
  10. 文章标题