本文刪簡自:www.zhangxinxu.com/wordpress/?…
一、功能體驗
先看demo:使用canvas在前端壓縮圖片並上傳demo
如下截圖:
點選檔案選擇框,我們不妨選一張尺寸比較大的圖片,例如下面這種2M多的釣魚收穫照:
於是圖片歘歘歘地傳上去了:
此時我們點選最終上傳完畢的圖片地址,會發現原來2M多3000多畫素寬的圖片被限制為400畫素寬了:
儲存到本地會發現圖片尺寸已經變成只有70K了:
以上就是圖片前端壓縮並上傳demo的完整演示。
二、實現原理
要想使用JS實現圖片的壓縮效果,原理其實很簡單,核心API就是使用canvas
的drawImage()
方法。
Canvas本質上就是一張點陣圖,而drawImage()
方法可以把一張大大的圖片繪製在小小的Canvas畫布上,不久等同於圖片尺寸壓縮了?
對於本案例的壓縮,使用的5個引數的API方法:
context.drawImage(img, dx, dy, dWidth, dHeight);
複製程式碼
各引數具體含義可以參見“Canvas API中文文件-drawImage”,這裡不展開。
舉例:
一張圖片(假設圖片物件是img
)的原始尺寸是4000*3000,現在需要把尺寸限制為400*300大小,很簡單,原理如下程式碼示意:
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = 400;
canvas.height = 300;
// 核心JS就這個context.drawImage(img,0,0,400,300);
複製程式碼
把大圖片畫在一張小畫布上,壓縮就這麼實現了,是不是簡單的有點超乎想象。
三、如果想要上傳或下載?
如果想要上傳圖片或者下載圖片,可以使用canvas.toDataURL()
或者canvas.toBlob()
方法先進行轉換。
canvas.toDataURL(mimeType, qualityArgument)複製程式碼
可以把畫布轉換成base64格式資訊影像資訊,純字元的圖片表示法。
其中:mimeType
表示canvas
匯出來的base64
圖片的型別,預設是png格式,也即是預設值是'image/png'
,我們也可以指定為jpg格式'image/jpeg'
或者webp等格式。file
物件中的file.type
就是檔案的mimeType型別,在轉換時候正好可以直接拿來用(如果有file物件)。qualityArgument
表示匯出的圖片質量,只要匯出為jpg
和webp
格式的時候此引數才有效果,預設值是0.92
,是一個比較合理的圖片質量輸出引數,通常情況下,我們無需再設定。
更多關於toDataURL()方法的資訊可以參見“Canvas API中文文件-toDataURL()”。
canvas.toBlob(callback, mimeType, qualityArgument)複製程式碼
可以把畫布轉換成Blob檔案,通常用在檔案上傳中,因為是二進位制的,對後端更加友好。
和toDataURL()
方法相比,toBlob()
方法是非同步的,因此多了個callback
引數,這個callback
回撥方法預設的第一個引數就是轉換好的blob
檔案資訊,本文一開始的demo案例中的檔案上傳就是將canvas
圖片轉換成二進位制的blob
檔案,然後再ajax
上傳的,程式碼如下:
// canvas轉為blob並上傳canvas.toBlob(function (blob) {
// 圖片ajax上傳 var xhr = new XMLHttpRequest();
// 開始上傳 xhr.open("POST", 'upload.php', true);
xhr.send(blob);
});
複製程式碼
更多關於toBlob()方法的資訊可以參見“Canvas API中文文件-toBlob()”。
一旦有了可傳輸的影像資料,上傳下載就好實現了。例如下載前端壓縮好的圖片,可以參考我上一篇在掘金髮布的文章:“純JS生成並下載各種文字檔案或圖片”。
四、總結
經過“圖片→canvas壓縮→圖片”三步曲,我們完成了圖片前端壓縮功能。
以上,感謝閱讀!