日常開發中經常會遇到上傳圖片的需求,隨著手機的蓬勃發展,現在拍出來的照片分辨率越來越高,隨之帶來的問題就是圖片占用空間越來越大,如果我們直接上傳圖片可能就會浪費很大一筆資源,本文主要講解基于 Vue + Vant ,實現移動端圖片選擇,并用 Canvas 壓縮圖片,最后上傳至服務器。還會封裝一個工具類,方便直接調用。
一、工具類封裝
先上代碼,封裝一個 CompressImageUtils 工具類:
定義的最大寬度和最大高度均為 500,如果圖片的寬高至少有一個超出了 500,都會被等比壓縮,不用擔心變形。可以根據自己項目需要改變maxWidth 和 maxHeight 。
這里直接把壓縮的最大高度和最大寬度寫死為 500 了,沒有在調用時傳。因為一個項目壓縮的邏輯和大小一般都一致的,沒必要在每次調用的時候傳。當然如果想寫的靈活一點,可以在 compressImage 方法里再把 maxWidth 、 maxHeight 和壓縮質量船上。
compressImage 方法返回的是 blob 值,根據服務端接口需要可以改為返回 base64,只需將 resolve(blob) 改為 resolve(base64) 即可。
注意一點,對于有些寬高沒到 500,且分辨率很小的圖片,壓縮之后可能比之前還大。猜測可能是 canvas 生成的圖片分辨率要比原來高一些,所以最終的圖片比壓縮前更大。可以在調用的地方加個判斷,如果壓縮完的大小比原圖小,就上傳壓縮后的圖片;如果如果壓縮完的大小比原圖大,就上傳原圖。
二、如何使用
將 CompressImageUtils 引入到目標文件,然后調用 compressImage 方法,即可在回調里獲得壓縮后的結果。注意 compressImage 方法返回的是 Promise。
省略其他無關代碼,只保留跟壓縮圖片和上傳相關的:
在返回結果中加了層判斷,壓縮后比原來更大,則將原圖上傳;壓縮后比原來小,上傳壓縮后的。解決壓縮后比原圖更大的情況。
三、使用效果
先上傳一個非常大的,尺寸為 6016?×?4016,16.8M 的大圖,看輸出日志,壓縮后大小僅為 260k 左右。此時判斷壓縮后比壓縮前小,上傳壓縮圖到服務器。
再看個尺寸 300?×?300,12k 的小圖,壓縮前大小是 11252,壓縮后大小是 93656,大了很多。此時判斷壓縮后比壓縮前更大,上傳的是原圖。
總結:這個工具類對大圖的壓縮效果很明顯,不管多大的圖,壓縮之后基本不會超過 300k。但對某些小圖可能出現壓縮完反而更大的情況。在調用的地方加層壓縮后和壓縮前大小的比較判斷,會完美解決這個問題。