android中如何压缩图片

2016-07-05  本文已影响0人  金馆长说

为什么需要压缩?

android中的图片是以Bitmap形式存在的,bitmap的大小和数量会直接影响到手机内存情况。不同大小的手机显示的图片也会不一样,跟分辨率、手机内存、显示的大小都有关系,所以很多时候我们需要对位图进行一些压缩的操作。

质量压缩不会减少图片的像素,它是在保持像素的前提下改变图片的位深及透明度,来达到压缩图片的目的,图片的长,宽,像素都不会改变,那么bitmap所占内存大小是不会变的。

计算bitmap大小
宽 * 高 * 一个像素点占用字节

四种压缩格式

[图片上传失败...(image-e55c37-1535879147605)]

ARGB代表的意思是

A(透明度)
R(red红色)
G(green绿色)
B(blue蓝色)

1. 质量压缩方式

质量压缩是在不改变图片大小的前提下,改变图片的位深以透明度,来达到压缩的目的。所以通过这种方式压缩的话,实际上我们内存加载进来的bitmap大小也是不会改变的。

但是这种方式会改变图片的文件大小,代码中可以看到通过了byteArray来判断大小,所以适合去传递二进制的图片数据,比如微信分享图片,要传入二进制数据过去,限制32kb之内。

 public static Bitmap compressByQuality(Bitmap src, long maxByteSize, boolean recycle) {
        if (isEmptyBitmap(src) || maxByteSize <= 0) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int quality = 100;
        src.compress(CompressFormat.JPEG, quality, baos);
        while (baos.toByteArray().length > maxByteSize && quality > 0) {
            baos.reset();
            src.compress(CompressFormat.JPEG, quality -= 5, baos);
        }
        if (quality < 0) {
            return null;
        }
        byte[] bytes = baos.toByteArray();
        if (recycle && !src.isRecycled()) {
            src.recycle();
        }
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

2. 采样率压缩
采样率压缩主要是通过BitmapFactory.Options类的inJustDecodeBunds标识为true,然后返回的bitmap就是一个Null对象,这样可以节约内存空间的开销。

但是这个bitmap的options是包含bitmap的宽高、MimeType参数。我们可以根据这些图片参数去设置options的 inSampleSize参数,通过这个参数我们可以实现图片大小的压缩。

主要压缩步骤

  1. BitmapFactory.Options的 inJustDecodeBunds为true并加载图片

  2. 从BitmapFactory.Options 中取出图片的原始宽高信息,对应outWidth和outHeight

  3. 根据采样率的规格并结合目标计算出View的所需大小计算出inSampleSize

  4. BitmapFactory.Options 的 inJustDecodeBunds 参数设置为false,然后重新加载图片

private Bitmap decodeSampleBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
   final BitmapFactory.Options options = new BitmapFactory.Options();
   options.inJustDecodeBounds = true;
   BitmapFactory.decodeResource(res, resId, options);
   options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
   options.inJustDecodeBounds = false;
   Bitmap bm = BitmapFactory.decodeFile(imagePath, options); 
   return bm;
}

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
   final int height = options.outHeight;
   final int width = options.outWidth;
   int inSampleSize = 1;
   if (height > reqHeight || width > reqWidth) {   
         final int halfHeight = height / 2;    
         final int halfWidth = height / 2;    
         while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {      
              inSampleSize *= 2;    
         }
   }
   return inSampleSize;
}

** 3. 缩放法压缩(martix)**

/**
     * 缩放图片
     *
     * @param src 源图片
     * @param scaleWidth 缩放宽度倍数
     * @param scaleHeight 缩放高度倍数
     * @param recycle 是否回收
     * @return 缩放后的图片
     */
    public static Bitmap scale(Bitmap src, float scaleWidth, float scaleHeight, boolean recycle) {
        if (isEmptyBitmap(src)) {
            return null;
        }
        Matrix matrix = new Matrix();
        matrix.setScale(scaleWidth, scaleHeight);
        Bitmap ret = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src
                .getHeight(), matrix, true);
        if (recycle && !src.isRecycled()) {
            src.recycle();
        }
        return ret;
    }

4. RGB_565压缩法

/**
     * rgb 565压缩
     * @param bm
     * @param path
     * @return
     */
    private Bitmap rgb565(Bitmap bm, String path) {
        BitmapFactory.Options options2 = new BitmapFactory.Options();
        options2.inPreferredConfig = Bitmap.Config.RGB_565;
        bm = BitmapFactory.decodeFile(path, options2);
        return bm;
    }

5 . createScaledBitmap方式压缩

 /**
     * 缩放图片
     *
     * @param src       源图片
     * @param newWidth  新宽度
     * @param newHeight 新高度
     * @param recycle   是否回收
     * @return 缩放后的图片
     */
    public static Bitmap scale(Bitmap src, int newWidth, int newHeight, boolean recycle) {
        if (isEmptyBitmap(src)) {
            return null;
        }
        Bitmap ret = Bitmap.createScaledBitmap(src, newWidth, newHeight, true);
        if (recycle && !src.isRecycled()) {
            src.recycle();
        }
        return ret;
    }
上一篇下一篇

猜你喜欢

热点阅读