请尊重他人的劳动成果,转载请注明出处:Android图片紧缩技能
http://blog.csdn.net/fengyuzhengfan/article/details/41759835
当需要将Android客户真个图片上传到服务器时,常常需要将图片进行紧缩,关于图片的紧缩方法,小编分享几种经常使用的方式:
第1种方式:裁切以到达紧缩的目的
我曾在《Android开发之裁剪照片》1文中详细介绍过如何裁切照片,感兴趣的朋友可以去看1下。
第2种方式:将图片进行降质处理(即下降图片的质量)以到达紧缩的目的
这类方式也是比较经常使用的方式,下面就为大家介绍如何对图片进行降质:
将图片降质我们可使用Bitmap的这个方法:boolean android.graphics.Bitmap.compress(CompressFormat format, int quality, OutputStream stream)
其中,参数format表示紧缩后的格式,quality紧缩后的图片质量(0表示最低,100表示不紧缩),stream表示要将紧缩后的图片保存到的输出流。
下面是详细代码:
/**
* 多线程紧缩图片的质量
* @author JPH
* @param bitmap 内存中的图片
* @param imgPath 图片的保存路径
* @date 2014⑴2⑸下午11:30:43
*/
public static void compressImageByQuality(final Bitmap bitmap,final String imgPath){
new Thread(new Runnable() {//开启多线程进行紧缩处理
@Override
public void run() {
// TODO Auto-generated method stub
ByteArrayOutputStream baos = new ByteArrayOutputStream();
options = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量紧缩方法,把紧缩后的数据寄存到baos中 (100表示不紧缩,0表示紧缩到最小)
while (baos.toByteArray().length / 1024 > 100) {//循环判断如果紧缩后图片是不是大于100kb,大于继续紧缩
baos.reset();//重置baos即让下1次的写入覆盖之前的内容
options -= 10;//图片质量每次减少10
if(options<0)options=0;//如果图片质量小于10,则将图片的质量紧缩到最小值
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//将紧缩后的图片保存到baos中
if(options==0)break;//如果图片的质量已降到最低则,不再进行紧缩
}
try {
FileOutputStream fos = new FileOutputStream(new File(imgPath));//将紧缩后的图片保存的本地上指定路径中
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
方法解析:
由于此方法中包括I/O操作和递归调用比较耗时所以我采取了多线程去处理。
第3种方式:按比例缩小图片的像素以到达紧缩的目的
此种方法主要是使用android.graphics.BitmapFactory.Options.Options()方法将图片以指定的采取率加载到内存然后输出到本地以到达紧缩像素的目的。
详细代码:
/**
* 按比例缩小图片的像素以到达紧缩的目的
* @author JPH
* @param imgPath
* @date 2014⑴2⑸下午11:30:59
*/
public static void compressImageByPixel(String imgPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;//只读边,不读内容
Bitmap bitmap = BitmapFactory.decodeFile(imgPath, newOpts);
newOpts.inJustDecodeBounds = false;
int width = newOpts.outWidth;
int height = newOpts.outHeight;
float maxSize = 1000f;//默许1000px
int be = 1;
if (width > height && width > maxSize) {//缩放比,用高或宽其中较大的1个数据进行计算
be = (int) (newOpts.outWidth / maxSize);
} else if (width < height && height > maxSize) {
be = (int) (newOpts.outHeight / maxSize);
}
be++;
newOpts.inSampleSize = be;//设置采样率
newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默许的,可不设
newOpts.inPurgeable = true;// 同时设置才会有效
newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
bitmap = BitmapFactory.decodeFile(imgPath, newOpts);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
try {
FileOutputStream fos = new FileOutputStream(new File(imgPath));
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
第4种方式:将图片先按比例紧缩然后再降质
此种方式主要结合第2种和第3种方法以下是详细代码:
/**
* 多线程紧缩图片的质量
* @author JPH
* @param bitmap 内存中的图片
* @param imgPath 图片的保存路径
* @date 2014⑴2⑸下午11:30:43
*/
public static void compressImageByQuality(final Bitmap bitmap,final String imgPath){
new Thread(new Runnable() {//开启多线程进行紧缩处理
@Override
public void run() {
// TODO Auto-generated method stub
ByteArrayOutputStream baos = new ByteArrayOutputStream();
options = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量紧缩方法,把紧缩后的数据寄存到baos中 (100表示不紧缩,0表示紧缩到最小)
while (baos.toByteArray().length / 1024 > 100) {//循环判断如果紧缩后图片是不是大于100kb,大于继续紧缩
baos.reset();//重置baos即让下1次的写入覆盖之前的内容
options -= 10;//图片质量每次减少10
if(options<0)options=0;//如果图片质量小于10,则将图片的质量紧缩到最小值
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//将紧缩后的图片保存到baos中
if(options==0)break;//如果图片的质量已降到最低则,不再进行紧缩
}
try {
FileOutputStream fos = new FileOutputStream(new File(imgPath));//将紧缩后的图片保存的本地上指定路径中
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
/**
* 按比例缩小图片的像素以到达紧缩的目的
* @author JPH
* @param imgPath
* @date 2014⑴2⑸下午11:30:59
*/
public static void compressImageByPixel(String imgPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;//只读边,不读内容
Bitmap bitmap = BitmapFactory.decodeFile(imgPath, newOpts);
newOpts.inJustDecodeBounds = false;
int width = newOpts.outWidth;
int height = newOpts.outHeight;
float maxSize = 1000f;//默许1000px
int be = 1;
if (width > height && width > maxSize) {//缩放比,用高或宽其中较大的1个数据进行计算
be = (int) (newOpts.outWidth / maxSize);
} else if (width < height && height > maxSize) {
be = (int) (newOpts.outHeight / maxSize);
}
be++;
newOpts.inSampleSize = be;//设置采样率
newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默许的,可不设
newOpts.inPurgeable = true;// 同时设置才会有效
newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
bitmap = BitmapFactory.decodeFile(imgPath, newOpts);
compressImageByQuality(bitmap,imgPath);//紧缩好比例大小后再进行质量紧缩
}