您的位置:首页 > 其它

图片的二次采样

2016-09-06 18:39 417 查看
一、图片处理
在开发app的过程中,当图片的尺寸较大或者图片的数量过多时,就容易出现OOM异常(内存溢出)
为了解决这个问题需要对图片进行处理,图片的处理包括两方面:质量压缩(不改变图片的尺寸)、尺寸压缩(相当于像素压缩) 质量压缩一般用于上传大图片之前的处理,可以节省流量;尺寸压缩一般生成缩略图。

尺寸压缩:
二次采样的目的?哪两次?
1、第一次采样

主要获得图片的压缩比例 ----例如:存在一张图片 200*200,想要将该图片压缩后显示到50*50 的ImageView中,那么压缩比例就是4,如何获得4?

先加载的图片的边界到内存中,加载边界的操作相对不会耗损太多内存,加载到内存后,就可以获取该图片的宽高参数,然后根据图片的宽度和高度再结合控件的宽度高度计算出压缩比例。
2、第二次采样

第二财采样是在第一次采样的基础上,将第一次采样的压缩比例结果作为参数传递给bitmapfactory对象,这样在加载图片时系统就不会将整张图片加载进来,而是只会加载该图片的一张缩略图,提高加载的速度,节省内存。

public class BitmapUtil {

/**

* 灵活的方法:获取期望的宽和高.

* 图片实际的宽与高,根据默认最大大小值,得到图片实际的缩放比例

*/

private static int getResizedDimension(int maxPrimary, int maxSecondary,int actualPrimary, int actualSecondary) {

if (maxPrimary == 0 && maxSecondary == 0) {

return actualPrimary;

}

if (maxPrimary == 0) {

double ratio = (double) maxSecondary / (double) actualSecondary;

return (int) (actualPrimary * ratio);

}

if (maxSecondary == 0) {

return maxPrimary;

}

double ratio = (double) actualSecondary / (double) actualPrimary;

int resized = maxPrimary;

if (resized * ratio > maxSecondary) {

resized = (int) (maxSecondary / ratio);

}

return resized;

}

//计算最佳采样率的方法.

public static int findBestSampleSize(int actualWidth, int actualHeight,

int desiredWidth, int desiredHeight) {

//1.73

double wr = (double) actualWidth / desiredWidth;

//1.73

double hr = (double) actualHeight / desiredHeight;

//1.73

double ratio = Math.min(wr, hr);

float n = 1.0f;

while ((n * 2) <= ratio) {

n *= 2;

}

return (int) n;

}

/**

* 图片二次采样的方法 图片的像素压缩 修改图片的宽度/高度 图片按照比例大小进行压缩

*/

public static Bitmap ParserBitmap(int maxWidth,int maxHeight,

byte[] data,Bitmap.Config config){

Bitmap bm=null;

//第一次采样

BitmapFactory.Options options=new BitmapFactory.Options();

if(maxWidth==0 && maxHeight==0){

//设置图片的位数 rgb_565 rgb_4444 rgb_8888

options.inPreferredConfig=config;

bm=BitmapFactory.decodeByteArray(data,0,data.length,options);

}else{

//该属性设置为true表示只加载图片的边框 不会加载图片的具体像素点 测量边界

options.inJustDecodeBounds=true;

//第一次加载图片 只加载图片的边框 并不加载像素点

BitmapFactory.decodeByteArray(data,0,data.length,options);

//图片的真实的宽度和高度 原图

int trueWidth=options.outWidth;

int trueHeight=options.outHeight;

//Log.i("tag","原图的宽度:"+trueWidth+",原图的高度:"+trueHeight);

//期望的宽度和高度

int desWidth=getResizedDimension(maxWidth,maxHeight,trueWidth,trueHeight);

int desHeight=getResizedDimension(maxHeight,maxWidth,trueHeight,trueWidth);

//也可以直接指定固定的值

// int desWidth=300;

// int desHeight=500;

//Log.i("tag","期望的宽度:"+desWidth+",期望的高度:"+desHeight);

//至此第一次采样结束 开始第二次采样

//第二次采样不仅只是加载图片的边缘

options.inJustDecodeBounds=false;

//inSampleSize 设置图片的采样率 获取压缩比例

options.inSampleSize=findBestSampleSize(trueWidth,trueHeight,desWidth,desHeight);

Log.i("tag","----options.inSampleSize-----"+ options.inSampleSize);

//生成临时的bitmap对象

Bitmap tempBitmap=BitmapFactory.decodeByteArray(data,0,data.length,options);

if(tempBitmap!=null || tempBitmap.getWidth()>desWidth

|| tempBitmap.getHeight()>desHeight){

//创建压缩后的bitmap对象

bm=tempBitmap.createScaledBitmap(tempBitmap,desWidth,desHeight,true);

tempBitmap.recycle();

}else{

bm=tempBitmap;

}

}

return bm;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图片二次采样