完全解決第三方分享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[]數組沒有必然的關係。

相關文章
相關標籤/搜索