压缩方法简介
质量压缩 方法:bitmap .compress(Bitmap.CompressFormat.JPEG, options, baos); 目的:将图片保存到本地时进行压缩, 即将图片从Bitmap形式变为File形式时进行压缩特点:能在一定程度减少图片的以File形式保存到磁盘时的大小,但不会减少图片的像素,也即不会减少图片加载到内存时占用的内存大小 该方法的官方文档解释说,它会让图片重新构造,但是有可能图像的位深(即色深)和每个像素的透明度会变化,JPEG onlysupports opaque(不透明),也就是说以 JPEG 格式压缩后,原来图片中透明的元素将消失。所以这种格式很可能造成失真 因为要保持像素不变,所以它无法无限压缩,到达一个值之后就不会继续变小了。
比例压缩 方法:bitmap = BitmapFactory.decodeFile(pathName, options); 目的:将图片从本地读到内存时进行压缩,即图片从File形式变为Bitmap形式时压缩 特点:通过设置采样率,减少图片的像素,达到对内存中的Bitmap进行压缩 注意:尽管在获取系统相册图片时,某些手机会直接返回一个Bitmap,但是这种情况下,返回的Bitmap都是经过压缩的,它不可能直接返回一个原生的Bitmap形式的图片
<!-- 在SDCard中读写、创建、删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
图片压缩工具类
public class ImageCompressUtils { /** * 建议压缩方式,计算合适的质量数 * @param bitmap 位图 * @param size 需要压缩到不超过这个大小 * @return 压缩质量,返回100表示不压缩 */ public static int getCompressQuality(Bitmap bitmap, int size) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (bitmap == null) { return 100; } bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int quality = 100; while (baos.toByteArray().length / 1024 > size) { //循环判断压缩后图片是否大于size,大于继续压缩 baos.reset();//重置baos即清空baos quality -= 2;//每次都减少2 if (quality <= 0) return 0;//注意,要保证options的值在[0,100]之间,否则会报异常 bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);//这里压缩options%,把压缩后的数据存放到baos中 } return quality; }
/** * 优化压缩方式,使用质量压缩法压缩图片,要求压缩后图片的大小不超过40kb */ private static Bitmap compressImageQuality(Bitmap bitmap) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int options = 100; while (true) { //循环判断如果压缩后图片是否大于40kb,大于继续压缩 if (baos.toByteArray().length / 1024 > 300) { options -= 32; } else if (baos.toByteArray().length / 1024 > 200) { options -= 22; } else if (baos.toByteArray().length / 1024 > 100) { options -= 17; } else if (baos.toByteArray().length / 1024 > 65) { options -= 6; } else if (baos.toByteArray().length / 1024 > 47) { options -= 3; } else if (baos.toByteArray().length / 1024 > 40) { options -= 2; } else { break; } if (options < 0) {//注意,要保证options的值在[0,100]之间,否则会报异常 break; } baos.reset();//重置baos即清空baos bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 } return BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.toByteArray().length); }
/** * 节省内存加载图片,并对图片进行压缩。调用此方法需要考虑返回的是null的情况 */ public static Bitmap compressBigImg(String pathName) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(pathName, options); //进行尺寸压缩 options.inSampleSize = calculateInSampleSize(options, 480, 800); Log.i("bqt", "inSampleSize:" + options.inSampleSize); options.inPurgeable = true; options.inInputShareable = true; options.inJustDecodeBounds = false; Bitmap bm = BitmapFactory.decodeFile(pathName, options); if (bm != null) {//按质量进行压缩到指定大小 return compressImageQuality(bm); } else { return null; } }
/** * 节省内存加载图片,并对图片进行压缩。调用此方法需要考虑返回的是null的情况 */ public static Bitmap compressBigImg(Context context, int resId) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(context.getResources(), resId, options); //进行尺寸压缩 options.inSampleSize = calculateInSampleSize(options, 480, 800); Log.i("bqt", "inSampleSize:" + options.inSampleSize); options.inPurgeable = true; options.inInputShareable = true; options.inJustDecodeBounds = false; Bitmap bm = BitmapFactory.decodeResource(context.getResources(), resId, options); if (bm != null) {//按质量进行压缩到指定大小 return compressImageQuality(bm); } else { return null; } }
/** * 根据设定大小获取压缩比 */ public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { int height = options.outHeight; int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { int heightRatio = Math.round((float) height / (float) reqHeight); int widthRatio = Math.round((float) width / (float) reqWidth); inSampleSize = heightRatio < widthRatio ? widthRatio : heightRatio; } return inSampleSize; }
/** * 根据inputstream压缩图片 */ public static Bitmap compressScaledBitmap(InputStream is, int width, int height) { if (is != null) { try { ByteArrayBuffer buff = new ByteArrayBuffer(64); ByteStreams.copy(is, buff); byte[] bytes = buff.buffer(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Config.ALPHA_8;//灰度照片 options.inPurgeable = true; options.inInputShareable = true; if (width != 0) { options.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);//byte数组,偏移量,长度 options.inSampleSize = calculateInSampleSize(options, width, height); options.inJustDecodeBounds = false; } return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); } catch (IOException e) { e.printStackTrace(); return null; } } else { return null; } }
/** * 保存bitmap */ public static boolean saveBitmap(Bitmap bitmap, String path) { FileOutputStream fos = null; try { fos = new FileOutputStream(new File(path)); bitmap.compress(Bitmap.CompressFormat.JPEG, 83, fos); fos.flush(); return true; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fos != null) fos.close(); } catch (IOException e) { e.printStackTrace(); return false; } } return false; } }
时间: 2024-10-29 19:11:00