2019年6月15日

前端如何使用 JS 先壓縮圖片尺寸大小再進行上傳,有效節省儲存空間﹍實作範例

前端如何使用 JS 先壓縮圖片尺寸大小再進行上傳,有效節省儲存空間﹍實作範例

Wayne Fu 0 A+
js-compress-resize-image-canvas.jpg-前端如何使用 JS 先壓縮圖片尺寸大小再進行上傳,有效節省儲存空間﹍實作範例以前處理過一個客製系統,有多處需要註冊會員上傳圖片:

  • 會員頭像
  • 證件留底
  • 設施環境介紹照片

由於使用者各種年齡層都有,不是每個人都網路世代,懂得先壓縮 JPG 檔再上傳,那麼上傳的圖片檔案可能會超出工程師想像。大部分中高齡使用者可能直接從手機選了圖片就上傳,也不會知道這張圖片到底多大。現在手機鏡頭越來越高級,照出來的圖片預設原始尺寸也越來越大,一張圖好幾 MB 是常態,超過 5MB 也是有可能的事。

以站長的角度,絕不願意儲存在後端的圖片,佔用這麼大的空間,除了要付更多費用,同時浪費頻寬、網頁存取速度也慢。

因此本篇介紹的 Javascript 技術非常實用,可以在上傳圖片之前,從前端就先改變圖片尺寸,並進行壓縮減少檔案大小,減少後端的作業及空間。

(圖片出處: pixabay.com)


一、上傳圖片的基本知識


1. 網路空間

上傳圖片功能最重要的是需先準備一個存放空間,如果是自架站就比較沒問題,使用自己的空間不會有任何限制。

如果沒有空間的話,那麼以本站作為舉例,「留言開放上傳圖片」功能,而圖片是則上傳到免費的 Google Drive,圖片的顯示使用 Google Drive 提供的分享連結(上傳後即可取得此連結),讓訪客另開視窗來看圖片。


2. 上傳按鈕

接下來在網頁上製作「上傳按鈕」,利用 HTML5 的 File API 取得圖片內容,再進行上傳。

這部分的範例程式碼,可參考這篇「前端操作 Apps Script 上傳檔案到 Google Drive 並取得連結」。



二、壓縮圖片原理


完整的原理說明,可參考這篇「圖片純前端JS壓縮的實現」,以下進行關鍵分解說明。


1. 調整圖片尺寸

取得圖片後,接下來需要利用 HTML5 Canvas 的「drawImage()」方法:

drawImage(圖片, 0, 0, 圖片寬度, 圖片高度)
使用這些參數後,可以更改圖片尺寸。


2. 壓縮圖片

上傳圖片之前,利用 Canvas 的「toBlob()」可設定壓縮比例:

canvas.toBlob(回傳函數, 檔案格式, 壓縮比例)

基本上要設定壓縮比例的話,通常要處理 jpg 檔,那麼可以用這樣的參數:

canvas.toBlob(callback, "image/jpeg", 0.8)
這樣代表 jpg 檔的壓縮比例為 80%。

如果檔案類型用 png、gif 檔是不能壓縮的,設定了壓縮比例會被無視。


3. 瀏覽器支援度

HTML5 Canvas 的 toBlob(),這個函數的使用說明及瀏覽器支援度請參考「HTMLCanvas​Element​.toBlob()」,看起來 IE、Edge 都是不支援的。



三、壓縮圖片範例程式碼


需先載入 jQuery、Bootstrap,如網頁已安裝過,請移除綠字部分的程式碼:

<label class="btn btn-info"><input id="upload_img" style="display:none;" type="file"><i class="fa fa-photo"></i> 上傳圖片</label>

<div id="oldImg"></div>

<div id="newImg"></div>

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"></link>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<script>
(function($) {
var compressRatio = 0.8, // 圖片壓縮比例
imgNewWidth = 400, // 圖片新寬度
img = new Image(),
canvas = document.createElement("canvas"),
context = canvas.getContext("2d"),
file, fileReader, dataUrl;

// 上傳檔案
$("#upload_img").change(function() {
file = this.files[0];
// 圖片才處理
if (file && file.type.indexOf("image") == 0) {
fileReader = new FileReader();
fileReader.onload = getFileInfo;
fileReader.readAsDataURL(file);
}
});

function getFileInfo(evt) {
dataUrl = evt.target.result,

// 取得圖片
img.src = dataUrl;
}

// 圖片載入後
img.onload = function() {
var width = this.width, // 圖片原始寬度
height = this.height, // 圖片原始高度
imgNewHeight = imgNewWidth * height / width, // 圖片新高度
html = "",
newImg;

// 顯示預覽圖片
html += "<img src='" + dataUrl + "'/>";
html += "<p>這裡是原始圖片尺寸 " + width + "x" + height + "</p>";
html += "<p>檔案大小約 " + Math.round(file.size / 1000) + "k</p>";
$("#oldImg").html(html);

// 使用 canvas 調整圖片寬高
canvas.width = imgNewWidth;
canvas.height = imgNewHeight;
context.clearRect(0, 0, imgNewWidth, imgNewHeight);

// 調整圖片尺寸
context.drawImage(img, 0, 0, imgNewWidth, imgNewHeight);

// 顯示新圖片
newImg = canvas.toDataURL("image/jpeg", compressRatio);
html = "";
html += "<img src='" + newImg + "'/>";
html += "<p>這裡是新圖片尺寸 " + imgNewWidth + "x" + imgNewHeight + "</p>";
html += "<p>檔案大小約 " + Math.round(0.75 * newImg.length / 1000) + "k</p>"; // 出處 https://stackoverflow.com/questions/18557497/how-to-get-html5-canvas-todataurl-file-size-in-javascript
$("#newImg").html(html);

// canvas 轉換為 blob 格式、上傳
canvas.toBlob(function(blob) {
// 輸入上傳程式碼
}, "image/jpeg", compressRatio);
};
})(jQuery);
</script>

  • compressRatio 參數 0.8 請改為自訂壓縮比
  • imgNewWidth 參數 400 請改為自訂寬度 px 值
  • 其餘說明請見程式註解,需要自訂功能請直接修改原始碼


js-compress-resize-image-canvas-1.jpg-前端如何使用 JS 先壓縮圖片尺寸大小再進行上傳,有效節省儲存空間﹍實作範例

此範例程式碼的效果大致如上圖,後面有展示用的「上傳按鈕」可自行玩玩看效果。



四、圖片壓縮效果展示


點擊下方的「上傳按鈕」,上傳 jpg 圖片後,會將圖片尺寸等比例縮小為 400px 寬,並壓縮為 80%,有效縮減檔案大小,又不降低圖片品質。








更多網頁開發工具:
0 0
如這篇文章對你有幫助,歡迎「分享」到 FB、「追蹤」粉絲團、「訂閱」最新文章

沒有留言:

張貼留言注意事項:

◎ 勾選「通知我」可收到後續回覆的mail!
◎ 請在相關文章留言,與文章無關的主題可至「Blogger 社團」提問。
◎ 提問若無法提供足夠的資訊供判斷,可能會被無視。建議先參考這篇「Blogger 提問技巧及注意事項」。
◎ CSS 相關問題非免費諮詢,建議使用「Chrome 開發人員工具」尋找答案。
◎ 手機版相關問題請參考「Blogger 行動版範本的特質」→「三、行動版範本不一定能執行網頁版工具」。
◎ 非官方範本問題、或貴站為商業網站,請參考「Blogger 免費諮詢 + 付費諮詢
◎ 若是使用官方 RWD 範本,請參考「Blogger 推出全新自適應 RWD 官方範本及佈景主題」→ 不建議對範本進行修改!
◎ 若留言要輸入語法,"<"、">"這兩個符號請用其他符號代替,否則語法會消失!
◎ 為了過濾垃圾留言,所有留言不會即時發佈,請稍待片刻。
◎ 本站「已關閉自刪留言功能」。

TOP