android图片压缩解决办法
2016-09-07 14:20
169 查看
对图片的尺寸大小进行缩放来达到压缩的目的
只是大家需要注意的是,这里需要按照原始图片的宽高比(srcRatio)来计算最终输出图片的宽高(actualOutWidth,actualOutHeight),最后通过actualOutWidth,actualOutHeight来计算采样值sampleSize。核心代码如下:
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(srcImagePath, options); //根据原始图片的宽高比和期望的输出图片的宽高比计算最终输出的图片的宽和高 float srcWidth = options.outWidth; float srcHeight = options.outHeight; float maxWidth = outWidth;//期望输出的图片宽度 float maxHeight = outHeight;//期望输出的图片高度 float srcRatio = srcWidth / srcHeight; float outRatio = maxWidth / maxHeight; float actualOutWidth = srcWidth;//最终输出的图片宽度 float actualOutHeight = srcHeight;//最终输出的图片高度 if (srcWidth > maxWidth || srcHeight > maxHeight) { if (srcRatio < outRatio) { actualOutHeight = maxHeight; actualOutWidth = actualOutHeight * srcRatio; } else if (srcRatio > outRatio) { actualOutWidth = maxWidth; actualOutHeight = actualOutWidth / srcRatio; } else { actualOutWidth = maxWidth; actualOutHeight = maxHeight; } } //计算sampleSize options.inSampleSize = computSampleSize(options, actualOutWidth, actualOutHeight);
举个极端例子:
假如原始图片宽为srcWidth=40,高为srcHeight=20。期望输出的宽为maxWidth=300,高为maxHeight=10。 那么srcRatio=40:20=2,outRatio=300:10=30. 显然srcRatio<outRatio,那么我们的实际最终输出图片的尺寸应该以maxHeight(10)为准即
actualOutHeight = maxHeight,最后根据原图的比率来计算actualOutWidth=actualOutHeight*srcRatio
= 10*40/20=20,最后得到的actualOutWidth=20. 最终输出图片的宽高比为20:10=2,和原始图片宽高比相同。其它情况类似,这里不做详解了。
对图片进行质量压缩
针对这种情况,android的Bitmap类中API接口有compress方法public boolean compress(CompressFormat format, int quality, OutputStream stream)
三个参数的理解应该不难,大家可以查看官方doc文档。compress方法主要通过quality来控制输入到stream中的像素质量。
这针对希望输出的图片占用的空间不大于一定的值这种场景会比较合适,因为我们可以通过循环判断压缩后的大小是否大于定值,如果满足则减少quality继续执行compress操作。核心代码如下:
//进行有损压缩 ByteArrayOutputStream baos = new ByteArrayOutputStream(); int options_ = 100; actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//质量压缩方法,把压缩后的数据存放到baos中 (100表示不压缩,0表示压缩到最小) int baosLength = baos.toByteArray().length; while (baosLength / 1024 > maxFileSize) {//循环判断如果压缩后图片是否大于maxMemmorrySize,大于继续压缩 baos.reset();//重置baos即让下一次的写入覆盖之前的内容 options_ = Math.max(0, options_ - 10);//图片质量每次减少10 actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//将压缩后的图片保存到baos中 baosLength = baos.toByteArray().length; if (options_ == 0)//如果图片的质量已降到最低则,不再进行压缩 break; }
压缩一个超大图是要费时间的,所以大家应该考虑将压缩放到后台线程中执行,如果没有高并发的需求使用AsyncTask就能解决问题。
核心代码:
private class CompressTask extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... params) { return compressImage();//执行压缩操作 } @Override protected void onPreExecute() { if (compressListener != null) { compressListener.onCompressStart();//监听回调(开始压缩) } } @Override protected void onPostExecute(String imageOutPath) { if (compressListener != null) { compressListener.onCompressEnd(imageOutPath);//监听回调(压缩结束) } } }
经过适当的封装代码可以通过在Activity中的执行
LGImgCompressor.getInstance(this).withListener(this). starCompress(Uri.fromFile(imageFile).toString(),outWidth,outHeight,maxFileSize);来启动压缩任务
具体参考demo开源github地址如下:
LGImageCompressor
相关文章推荐
- react-native-image-picker在Android上闪退的解决办法(上传头像base64,压缩上传图片)
- Android中 在显示ImageView时图片上面和下面都出现一段空白区间的解决办法
- Android GridView 一行显示数据(包括图片和文本),解决的办法是计算数据占该行的宽度是多少
- cocos2d-android 在大分辨率下图片拉伸的解决办法
- Android 图片加载Bitmap OOM错误解决办法
- android端读取本地图片出现OutOfMemoryException解决办法
- android:drawableLeft的Button不能切换图片问题之解决办法
- Android中 在显示ImageView时图片上面和下面都出现一段空白区间的解决办法
- Android相机、相册获取图片,解决相机拍照图片被压缩模糊的情况
- Android图片复古拉伸解决办法参考
- Android保存图片到系统不能及时生成缩略图的解决办法
- Android--在显示ImageView时图片上面和下面都出现一段空白区间的解决办法
- Android GridView 一行显示数据(包括图片和文本),解决的办法是计算数据占该行的宽度是多少
- Android CheckBox自定义图片没效果--解决办法
- 【游戏开发备注之一】关于Cocos2dx_v1.x版本iphone与Android运行出现图片白块、添加GameCenter报错问题及编译Android闪退的解决办法&&CCLOG与CClog的区别
- 关于Android平台下png图片渐变失真的解决办法
- eclipse android 开发加载图片资源提示找不到对应名称解决办法
- android 加载本地图片报内存溢(out of memory)解决办法一
- ueditor1.2.6图片被压缩的解决办法
- Android CheckBox自定义图片没效果--解决办法