您的位置:首页 > 移动开发 > Android开发

【Android】图像压缩 (在GridView等中使用缩略图提高响应速度)

2016-07-25 15:05 501 查看
  随着手机摄像头像素的提升,拍摄的照片大小也越来越大,在GridView等控件中列举图片等内容,会因为图片太大从而在setImage的时候耗费过多的时间,导致用户体验度下降,所以我们在获取到图像uri的时候将图像进行压缩后单独保存一份,在GridView中显示缩略图,而item的点击事件还是依旧传输的是原图的链接地址,从而保证查看大图时显示的是原图内容。

  本例中所说的图片来源于从系统图库中选取的图片或者由相机拍摄并返回的图片,将这些图片都显示在GridView当中。由于之前的文章叙述过从系统图库中选取的图片和由相机拍摄并返回的图片的方式以及GridView的adapter如何实现,这里不再赘述,只附上关键部分的代码。

  在调用拍照得到图片的过程中,我们图片的文件名及路径如下

image_camera_file = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg"); //设置sdcard的路径及图片文件名


  在onActivityResult中,

  

if (requestCode==RESULT_ADD_PIC_FROM_CAMERA && resultCode==RESULT_OK) {
try{
String c=Uri.fromFile(image_camera_file).toString();
list_image.add(c);
resultimage+="@"+Uri.fromFile(image_camera_file).toString();
//生成缩略图
Bitmap bitmap=getBitmapFormUri(ContentActivity.this,Uri.fromFile(image_camera_file));
File thumbnailfile=new File(Environment.getExternalStorageDirectory(),"thumbnail"+c.substring(c.lastIndexOf('/')+1));
Log.v("TAG",thumbnailfile.toString());
try {
FileOutputStream out = new FileOutputStream(thumbnailfile);
bitmap.compress(Bitmap.CompressFormat.JPEG,100,out);
out.flush();
out.close();
}catch (Exception e){
Log.getStackTraceString(e);
}
upgradethePage();
}
//记得要用异常捕获
catch (Exception e)
{
Log.getStackTraceString(e);
}

}


  这里,若原来的文件名为123.jpg 则缩略图的文件名为thumbnail123.jpg

  同理,对于从图库取出来的图片,由于返回的是系统数据库地址,所以我们根据其编号对缩略图进行命名。

  

if (requestCode==RESULT_ADD_PIC_FROM_ALBUM && resultCode==RESULT_OK) {
try{
Uri imageuri = data.getData();
list_image.add(imageuri.toString());
resultimage += "@" + imageuri.toString();
//生成缩略图
String s=imageuri.toString();
String c=s.substring(s.lastIndexOf('/') + 1);
File thumbnailfile=new File(Environment.getExternalStorageDirectory(),c+"thumbnail"+".jpg");
Bitmap bitmap=getBitmapFormUri(ContentActivity.this,imageuri);
try {
FileOutputStream out = new FileOutputStream(thumbnailfile);
bitmap.compress(Bitmap.CompressFormat.JPEG,100,out);
out.flush();
out.close();
}catch (Exception e){
Log.getStackTraceString(e);
}
upgradethePage();

}
catch (Exception e)
{
Log.getStackTraceString(e);
}
}


代码中用的图像压缩(产生缩略图)代码如下

//--------------------------------图像压缩------------------------------------------
private   Bitmap getBitmapFormUri(Activity ac, Uri uri) throws IOException {
InputStream input = ac.getContentResolver().openInputStream(uri);
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;
onlyBoundsOptions.inDither = true;//optional
onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
input.close();
int originalWidth = onlyBoundsOptions.outWidth;
int originalHeight = onlyBoundsOptions.outHeight;
if ((originalWidth == -1) || (originalHeight == -1))
return null;
float hh = ac.getResources().getDisplayMetrics().density*100+0.5f;
float ww = hh;

int be = 1;//be=1表示不缩放
if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大的话根据宽度固定大小缩放
be = (int) (originalWidth / ww);
} else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高的话根据高度固定大小缩放
be = (int) (originalHeight / hh);
}
if (be <= 0)
be = 2;
//比例压缩
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize =be;//设置缩放比例
bitmapOptions.inDither = true;//optional
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional
input = ac.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
// return bitmap;
return compressImage(bitmap);//再进行质量压缩
}
private   Bitmap compressImage(Bitmap image) {

ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 90, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 50;
while (baos.toByteArray().length / 1024 > 30) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();//重置baos即清空baos
//第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差  ,第三个参数:保存压缩后的数据的流
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
options -= 10;//每次都减少10
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
return bitmap;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息