Android-图片的压缩(质量压缩和尺寸压缩)
图片存在的几种形式
- File:存在于我们的磁盘中,我们通常说的图片大小。
- Stream即流的形式,比如我们上传网络图片。
- Bitmap,就是我们通常指内存中图片的大小。
质量压缩:
图片的质量压缩,会改变图片在磁盘中的大小(File文件的大小),不会改变图片在加载时,在内存的大小。
原理:
保持像素的前提下改变图片的位深及透明度,(即:通过算法抠掉(同化)了图片中的一些某个些点附近相近的像素),达到降低质量压缩文件大小的目的。
使用场景:
将压缩后的图片上传到服务器,或者保存到本地。具体结合实际需求。
/*** 质量压缩方法** @param image* @return*/public static Bitmap compressImage(Bitmap image) {ByteArrayOutputStream baos = new ByteArrayOutputStream();image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中int options = 100;while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于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;}/*** 质量压缩* 设置bitmap options属性,降低图片的质量,像素不会减少* 第一个参数为需要压缩的bitmap图片对象,第二个参数为压缩后图片保存的位置* 设置options 属性0-100,来实现压缩** @param bmp* @param file*/ public static void qualityCompress(Bitmap bmp, File file) {// 0-100 100为不压缩int quality = 20;ByteArrayOutputStream baos = new ByteArrayOutputStream();// 把压缩后的数据存放到baos中bmp.compress(Bitmap.CompressFormat.JPEG, quality, baos);try {FileOutputStream fos = new FileOutputStream(file);fos.write(baos.toByteArray());fos.flush();fos.close();} catch (Exception e) {e.printStackTrace();}}
尺寸压缩
原理:通过减少单位尺寸的像素值,正真意义上的降低像素;
使用场景:缓存缩略图的时候(头像处理);
/*** 压缩图片使用,采用BitmapFactory.decodeFile。这里是尺寸压缩* @param context* @param imageUri* @return*/public Bitmap bitmapFactory(Context context,Uri imageUri){String[] filePathColumns = {MediaStore.Images.Media.DATA};Cursor c = context.getContentResolver().query(imageUri, filePathColumns, null, null, null);c.moveToFirst();int columnIndex = c.getColumnIndex(filePathColumns[0]);String imagePath = c.getString(columnIndex);c.close();// 配置压缩的参数BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true; //获取当前图片的边界大小,而不是将整张图片载入在内存中,避免内存溢出BitmapFactory.decodeFile(imagePath, options);options.inJustDecodeBounds = false;inSampleSize的作用就是可以把图片的长短缩小inSampleSize倍,所占内存缩小inSampleSize的平方options.inSampleSize = caculateSampleSize(options,500,50);Bitmap bm = BitmapFactory.decodeFile(imagePath, options); // 解码文件return bm;}/*** 计算出所需要压缩的大小* @param options* @param reqWidth 我们期望的图片的宽,单位px* @param reqHeight 我们期望的图片的高,单位px* @return*/private int caculateSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {int sampleSize = 1;int picWidth = options.outWidth;int picHeight = options.outHeight;if (picWidth > reqWidth || picHeight > reqHeight) {int halfPicWidth = picWidth / 2;int halfPicHeight = picHeight / 2;while (halfPicWidth / sampleSize > reqWidth || halfPicHeight / sampleSize > reqHeight) {sampleSize *= 2;}}return sampleSize;}
总结
- 质量压缩无法避免OOM,但是可以改变图片在磁盘中或者说是File文件的大小,尺寸压缩可以避免OOM,但不改变图片本身的大小,只改变加载时在内存中的大小即Bitmap。
- 质量压缩我们的主要方法是:MediaStore.Images.Media.getBitmap或者BitmapFactory.decodeStream;尺寸压缩我们用到的方法是:BitmapFactory.decodeFile。
- 对于资源图片直接使用:tiny压缩
- 对图片裁剪的库鲁班库
- 它可以满足动则几MB的图片高保真的压缩到几十KB的效果。https://github.com/zetbaitsu/Compressor
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
