概述
内容如题:
以前对于图片缩放时出现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,从新构建bitmap
options.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 );启动后的返回结果处理
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case OPEN_PHOTO_REQUESTCODE:
if (resultCode == RESULT_OK) {
Bitmap bitmap = null;
// 将返回的数据构建成bitmap
try {
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() {
@Override
public 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
附件是完整的程序代码
最后
以上就是酷炫芝麻为你收集整理的android图片的打开和缩放时出现oom处理过程的全部内容,希望文章能够帮你解决android图片的打开和缩放时出现oom处理过程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复