Android 图片加载之图片压缩

1.降低分辨率

public static Bitmap decodeSampledBitmapFromResource(String path, int resId,
                                                         int reqWidth, int reqHeight) {
        // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        // 调用上面定义的方法计算inSampleSize值
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // 使用获取到的inSampleSize值再次解析图片
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(path, options);
    }
    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 heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
            // 一定都会大于等于目标的宽和高。
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }

2.减少每个像素点大小

系统默认是以 ARGB_8888 格式进行处理,那么每个像素点就要占据 4B 的大小,改变这个格式自然就能降低图片占据内存的大小
常见的是,将 ARGB_8888 换成 RGB_565 格式,但后者不支持透明度,所以此方案并不通用,取决于你 app 中图片的透明度需求,当然也可以缓存 ARGB_4444,但会降低质量。

public static enum Config {
        ALPHA_8,
        /** @deprecated */
        @Deprecated
        ARGB_4444,
        ARGB_8888,
        HARDWARE,
        RGBA_F16,
        RGB_565;
 
        private Config() {
        }
    }

像素值的获取和存储结构:

Bitmap bmp = Bitmap.createBitmap(10,10,Bitmap.Config.ARGB_8888);
        //背景填充白色
        bmp.eraseColor(Color.WHITE);
        //创建存储像素的数组
        int pixels[] = new int[bmp.getWidth() * bmp.getHeight()];
        //取得像素数据
        bmp.getPixels(pixels, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());

pixels即是我们取到的图像数据,虽然是length=100的一维数组,但是我们也可以理解为是10x10的图片

反向创建了白色的图片:

int width = 10;
int height = 10;
int pixels[] = new int[width * height];
for (int i = 0; i < pixels.length; i++) {
    pixels[i] = Color.argb(255, 255, 255, 255);
}
Bitmap bmp = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888);

推荐阅读更多精彩内容