如何壓縮一張圖片

語言: CN / TW / HK

「這是我參與2022首次更文挑戰的第5天,活動詳情檢視:2022首次更文挑戰

如何壓縮一張圖片

圖片的應用場景就太多了,如何處理好一張圖片,保證清晰度的同時佔用空間又小,成為首要的追求目標,那麼如何壓縮一張圖片?

圖片格式

不知道大家有沒有遇到這樣的場景,用壓縮工具壓縮一個100M的JPG圖片資料夾,壓縮後大概就在95M左右,而其它檔案則可以壓縮50M以上。

這是因為JPG是已經壓縮過的一種格式。

圖片也有眾多的編碼格式,比如說,jpg、png、bmp等都是我們常見的圖片格式,那麼這些圖片格式有什麼區別呢?

  • JPG是一種有失真壓縮的編碼,它出了色彩空間轉換,取樣率,分塊處理技術後,還採用哈夫曼(Huffman)編碼方式。 由於會將RGB顏色陣列換算成YUV然後降低UV的取樣率,所以這是一種壓縮演算法。

  • png是一種無失真壓縮編碼,增加透明度的通道,能在不失真的情況下降低影象檔案的大小,由於是無失真壓縮,並且用了透明度支援,所以相同的檔案下,要比JPG記憶體佔用大

  • BMP代指點陣圖(Bitmap),是未經過壓縮的編碼,所以它佔用的記憶體很大。

壓縮方式

  • 圖片大小

  • 圖片質量

  • 圖片編碼

從根本上講,圖片壓縮總是圍繞著這三個方向進行開展的。

由於現在裝置相機拍照的解析度很高,雖然圖片的質量有所提高,但原始圖片就會佔用很大空間,如果是在網路上傳輸,或者進行簡單的預覽,就沒有必要,比如上傳頭像等場景中。所以我們會壓縮圖片的大小,使其在滿足業務場景下也減少大小佔用。

在Android中壓縮圖片大小的演算法舉例:

```

public static void compressBitmapToFile(Bitmap bmp, File file){

// 壓縮的倍數

int ratio = 2;

Bitmap result = Bitmap.createBitmap(bmp.getWidth() / ratio, bmp.getHeight() / ratio, Config.ARGB_8888);

Canvas canvas = new Canvas(result);

Rect rect = new Rect(0, 0, bmp.getWidth() / ratio, bmp.getHeight() / ratio);

canvas.drawBitmap(bmp, null, rect, null);

ByteArrayOutputStream baos = new ByteArrayOutputStream();

result.compress(Bitmap.CompressFormat.JPEG, 100 ,baos);

try {

FileOutputStream fos = new FileOutputStream(file);

fos.write(baos.toByteArray());

fos.flush();

fos.close();

} catch (Exception e) {

e.printStackTrace();

}

}

```

質量壓縮也有兩個方向,一種是通過壓縮位深和透明度減少質量,另外一種是通過取樣率來進行壓縮。

在Android中的方法舉例

```

Bitmap bitmap;

bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);

//質量壓縮方法,調節options的值,這裡100表示不壓縮,把壓縮後的資料存放到baos中

```

```

options.inSampleSize = computeSize();

```

圖片編碼上面,除了常見的JPG、PNG之外,目前很多大公司都開始使用webp格式,它具有更優的影象資料壓縮演算法,所以體積更小。

在AndroidStudio中將圖片轉換成webp格式。

對著圖片檔案右鍵,然後點選 Convert to WebP,然後調節設定就可以了。

如何載入webp,在Android中不能像載入普通圖片一樣載入webP,目前主流的圖片載入框架都已經支援webp。