Android设备的内存有限,对于大图片,必须进行压缩后再进行显示,否则会出现内存溢出:OOM;
处理策略:
1.使用缩略图(Thumbnails);
Android系统会给检测到的图片创建缩略图;可以操作Media内容提供者中的Image对图片进行操作;
2.手动压缩:
- (1)根据图片和屏幕尺寸,等比压缩,完美显示;
- (2)降低图片质量,压缩图片大小;
以下是自己整理的小工具类(对于按比例缩放后,在此并未再进行质量缩放,此时图片大小有可能超出我们期望的限制;假如我们有严格的大小限制需求,可先进行按比例缩放后,判断此时图片大小是否超出限制;如果超出限制,对其再进行质量缩放即可。建议使用按比例缩放,按质量缩放很有可能导致图片失真。)
packagecom.util;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.io.InputStream;
importandroid.graphics.Bitmap;
importandroid.graphics.Matrix;
importandroid.graphics.Bitmap.CompressFormat;
importandroid.graphics.BitmapFactory;
importandroid.media.ExifInterface;
/**
*图片压缩工具类
*@author丶Life_
*/
publicclassImageCompressUtil{
/**
*通过降低图片的质量来压缩图片
*@parambmp
*要压缩的图片位图对象
*@parammaxSize
*压缩后图片大小的最大值,单位KB
*@return压缩后的图片位图对象
*/
publicstaticBitmapcompressByQuality(Bitmapbitmap,intmaxSize){
ByteArrayOutputStreambaos=newByteArrayOutputStream();
intquality=100;
bitmap.compress(CompressFormat.JPEG,quality,baos);
System.out.println("图片压缩前大小:"+baos.toByteArray().length+"byte");
booleanisCompressed=false;
while(baos.toByteArray().length/1024>maxSize){
quality-=10;
baos.reset();
bitmap.compress(CompressFormat.JPEG,quality,baos);
System.out.println("质量压缩到原来的"+quality+"%时大小为:"
+baos.toByteArray().length+"byte");
isCompressed=true;
}
System.out.println("图片压缩后大小:"+baos.toByteArray().length+"byte");
if(isCompressed){
BitmapcompressedBitmap=BitmapFactory.decodeByteArray(
baos.toByteArray(),0,baos.toByteArray().length);
recycleBitmap(bitmap);
returncompressedBitmap;
}else{
returnbitmap;
}
}
/**
*传入图片url,通过压缩图片的尺寸来压缩图片大小
*@parampathName图片的完整路径
*@paramtargetWidth缩放的目标宽度
*@paramtargetHeight缩放的目标高度
*@return缩放后的图片
*/
publicstaticBitmapcompressBySize(StringpathName,inttargetWidth,
inttargetHeight){
BitmapFactory.Optionsopts=newBitmapFactory.Options();
opts.inJustDecodeBounds=true;//不去真的解析图片,只是获取图片的头部信息,包含宽高等;
Bitmapbitmap=BitmapFactory.decodeFile(pathName,opts);
//得到图片的宽度、高度;
intimgWidth=opts.outWidth;
intimgHeight=opts.outHeight;
//分别计算图片宽度、高度与目标宽度、高度的比例;取大于等于该比例的最小整数;
intwidthRatio=(int)Math.ceil(imgWidth/(float)targetWidth);
intheightRatio=(int)Math.ceil(imgHeight/(float)targetHeight);
if(widthRatio>1||heightRatio>1){
if(widthRatio>heightRatio){
opts.inSampleSize=widthRatio;
}else{
opts.inSampleSize=heightRatio;
}
}
//设置好缩放比例后,加载图片进内容;
opts.inJustDecodeBounds=false;
bitmap=BitmapFactory.decodeFile(pathName,opts);
returnbitmap;
}
/**
*传入bitmap,通过压缩图片的尺寸来压缩图片大小
*@parambitmap要压缩图片
*@paramtargetWidth缩放的目标宽度
*@paramtargetHeight缩放的目标高度
*@return缩放后的图片
*/
publicstaticBitmapcompressBySize(Bitmapbitmap,inttargetWidth,
inttargetHeight){
ByteArrayOutputStreambaos=newByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG,100,baos);
BitmapFactory.Optionsopts=newBitmapFactory.Options();
opts.inJustDecodeBounds=true;
bitmap=BitmapFactory.decodeByteArray(baos.toByteArray(),0,
baos.toByteArray().length,opts);
//得到图片的宽度、高度;
intimgWidth=opts.outWidth;
intimgHeight=opts.outHeight;
//分别计算图片宽度、高度与目标宽度、高度的比例;取大于该比例的最小整数;
intwidthRatio=(int)Math.ceil(imgWidth/(float)targetWidth);
intheightRatio=(int)Math.ceil(imgHeight/(float)targetHeight);
if(widthRatio>1||heightRatio>1){
if(widthRatio>heightRatio){
opts.inSampleSize=widthRatio;
}else{
opts.inSampleSize=heightRatio;
}
}
//设置好缩放比例后,加载图片进内存;
opts.inJustDecodeBounds=false;
BitmapcompressedBitmap=BitmapFactory.decodeByteArray(
baos.toByteArray(),0,baos.toByteArray().length,opts);
recycleBitmap(bitmap);
returncompressedBitmap;
}
/**
*通过压缩图片的尺寸来压缩图片大小,通过读入流的方式,可以有效防止网络图片数据流形成位图对象时内存过大的问题;
*@paramInputStream要压缩图片,以流的形式传入
*@paramtargetWidth缩放的目标宽度
*@paramtargetHeight缩放的目标高度
*@return缩放后的图片
*@throwsIOException读输入流的时候发生异常
*/
publicstaticBitmapcompressBySize(InputStreamis,inttargetWidth,
inttargetHeight)throwsIOException{
ByteArrayOutputStreambaos=newByteArrayOutputStream();
byte[]buff=newbyte[1024];
intlen=0;
while((len=is.read(buff))!=-1){
baos.write(buff,0,len);
}
byte[]data=baos.toByteArray();
BitmapFactory.Optionsopts=newBitmapFactory.Options();
opts.inJustDecodeBounds=true;
Bitmapbitmap=BitmapFactory.decodeByteArray(data,0,data.length,
opts);
//得到图片的宽度、高度;
intimgWidth=opts.outWidth;
intimgHeight=opts.outHeight;
//分别计算图片宽度、高度与目标宽度、高度的比例;取大于该比例的最小整数;
intwidthRatio=(int)Math.ceil(imgWidth/(float)targetWidth);
intheightRatio=(int)Math.ceil(imgHeight/(float)targetHeight);
if(widthRatio>1||heightRatio>1){
if(widthRatio>heightRatio){
opts.inSampleSize=widthRatio;
}else{
opts.inSampleSize=heightRatio;
}
}
//设置好缩放比例后,加载图片进内存;
opts.inJustDecodeBounds=false;
bitmap=BitmapFactory.decodeByteArray(data,0,data.length,opts);
returnbitmap;
}
/**
*旋转图片摆正显示
*@paramsrcPath
*@parambitmap
*@return
*/
publicstaticBitmaprotateBitmapByExif(StringsrcPath,Bitmapbitmap){
ExifInterfaceexif;
BitmapnewBitmap=null;
try{
exif=newExifInterface(srcPath);
if(exif!=null){//读取图片中相机方向信息
intori=exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
intdigree=0;
switch(ori){
caseExifInterface.ORIENTATION_ROTATE_90:
digree=90;
break;
caseExifInterface.ORIENTATION_ROTATE_180:
digree=180;
break;
caseExifInterface.ORIENTATION_ROTATE_270:
digree=270;
break;
}
if(digree!=0){
Matrixm=newMatrix();
m.postRotate(digree);
newBitmap=Bitmap.createBitmap(bitmap,0,0,
bitmap.getWidth(),bitmap.getHeight(),m,true);
recycleBitmap(bitmap);
returnnewBitmap;
}
}
}catch(IOExceptione){
e.printStackTrace();
}
returnbitmap;
}
/**
*回收位图对象
*@parambitmap
*/
publicstaticvoidrecycleBitmap(Bitmapbitmap){
if(bitmap!=null&&!bitmap.isRecycled()){
bitmap.recycle();
System.gc();
bitmap=null;
}
}
}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。如果你想了解更多相关内容请查看下面相关链接