完全解决第三方分享icon过大的问题

不少第三方分享SDK对于分析的icon的bitmap大小作了强制要求,好比32kb,那么咱们须要对于即将要经过intent传递的bitmap作一个压缩,保证不会引发异常。git

先来对色彩空间作一个了解

ARGB_8888:
32位(4byte),4个byte描述四个不一样的参数(alpha,red,green,blue)。BitmapFactory加载时默认参数。github

Bitmap.Config.ARGB_8888。数组

RGB_565:
16位(2byte),3个byte分别描述三个参数(red,green,blue),也就是说不支持透明度。bash

options.inPreferredConfig = Bitmap.Config.RGB_565;ui

RGB_565天然比ARGB_8888小,是它的一半,代价是没有透明度。spa

Bitmap的大小计算公式

大小=(宽×缩放比)×(高×缩放比)×色彩空间code

好比在作第三方分享的时候,咱们都会用没有透明度的图片,也就是用RGB_565,这里的色彩空间就是2,缩放比为1。orm

下面是经过最终大小获得缩放后的bitmap的代码:cdn

Bitmap thumbBmp(@DrawableRes int drawableRes, long size) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.RGB_565;
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), drawableRes, options);

    int width = (int) Math.sqrt(size / 2); // 用了Bitmap.Config.RGB_565,这里除以2
    return Bitmap.createScaledBitmap(bitmap, width, width, true);
}
复制代码

更合理的压缩方案

上述的方案获得的bitamp是彻底符合标准的,经过bmp.getByteCount()能够进行检查。可是咱们传递的时候能够选择直接传递byte[],那么就不用考虑色彩空间这种和展现相关的变量了,在参考AdvancedLuban这个库后,咱们获得了下面的更优代码:blog

@Nullable
static byte[] getImageThumbByteArr(@Nullable Bitmap bitmap) {
    if (bitmap == null) {
        return null;
    }
    
    final long size = '耀';

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(bitmap.getWidth() * bitmap.getHeight());

    int options = 100;
    bitmap.compress(Bitmap.CompressFormat.JPEG, options, outputStream);

    while (outputStream.size() > size && options > 6) {
        outputStream.reset();
        options -= 6;
        bitmap.compress(Bitmap.CompressFormat.JPEG, options, outputStream);
    }

    bitmap.recycle();

    return outputStream.toByteArray();
}
复制代码

上面的代码是根据须要输出的byte[]大小进行循环的质量压缩,每次减小6,这样获得最接近于目标size的byte[]。这里的6能够自行修改,size = '耀'表示最大大小为32768。

上面三幅图,图一是原图,图二是用第一种方案获得的,图三是经过较优方案获得的。能够明显看到图三的质量最为接近于原图。

这里须要说明的是,图中的数字是bitmap解析后的bitmap的大小,和传递的byte[]数组没有必然的关系。

相关文章
相关标签/搜索