以前處理過一個客製系統,有多處需要註冊會員上傳圖片:
由於使用者各種年齡層都有,不是每個人都網路世代,懂得先壓縮 JPG 檔再上傳,那麼上傳的圖片檔案可能會超出工程師想像。大部分中高齡使用者可能直接從手機選了圖片就上傳,也不會知道這張圖片到底多大。現在手機鏡頭越來越高級,照出來的圖片預設原始尺寸也越來越大,一張圖好幾 MB 是常態,超過 5MB 也是有可能的事。
以站長的角度,絕不願意儲存在後端的圖片,佔用這麼大的空間,除了要付更多費用,同時浪費頻寬、網頁存取速度也慢。
因此本篇介紹的 Javascript 技術非常實用,可以在上傳圖片之前,從前端就先改變圖片尺寸,並進行壓縮減少檔案大小,減少後端的作業及空間。
(圖片出處: pixabay.com)
1. 網路空間
上傳圖片功能最重要的是需先準備一個存放空間,如果是自架站就比較沒問題,使用自己的空間不會有任何限制。
如果沒有空間的話,那麼以本站作為舉例,「留言開放上傳圖片」功能,而圖片是則上傳到免費的 Google Drive,圖片的顯示使用 Google Drive 提供的分享連結(上傳後即可取得此連結),讓訪客另開視窗來看圖片。
2. 上傳按鈕
接下來在網頁上製作「上傳按鈕」,利用 HTML5 的 File API 取得圖片內容,再進行上傳。
這部分的範例程式碼,可參考這篇「前端操作 Apps Script 上傳檔案到 Google Drive 並取得連結」。
完整的原理說明,可參考這篇「圖片純前端JS壓縮的實現」,以下進行關鍵分解說明。
1. 調整圖片尺寸
取得圖片後,接下來需要利用 HTML5 Canvas 的「drawImage()」方法:
使用這些參數後,可以更改圖片尺寸。
2. 壓縮圖片
上傳圖片之前,利用 Canvas 的「toBlob()」可設定壓縮比例:
基本上要設定壓縮比例的話,通常要處理 jpg 檔,那麼可以用這樣的參數:
這樣代表 jpg 檔的壓縮比例為 80%。
如果檔案類型用 png、gif 檔是不能壓縮的,設定了壓縮比例會被無視。
3. 瀏覽器支援度
HTML5 Canvas 的 toBlob(),這個函數的使用說明及瀏覽器支援度請參考「HTMLCanvasElement.toBlob()」,看起來 IE、Edge 都是不支援的。
需先載入 jQuery、Bootstrap,如網頁已安裝過,請移除綠字部分的程式碼:
此範例程式碼的效果大致如上圖,後面有展示用的「上傳按鈕」可自行玩玩看效果。
點擊下方的「上傳按鈕」,上傳 jpg 圖片後,會將圖片尺寸等比例縮小為 400px 寬,並壓縮為 80%,有效縮減檔案大小,又不降低圖片品質。
- 會員頭像
- 證件留底
- 設施環境介紹照片
由於使用者各種年齡層都有,不是每個人都網路世代,懂得先壓縮 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(),這個函數的使用說明及瀏覽器支援度請參考「HTMLCanvasElement.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 值
- 其餘說明請見程式註解,需要自訂功能請直接修改原始碼
此範例程式碼的效果大致如上圖,後面有展示用的「上傳按鈕」可自行玩玩看效果。
四、圖片壓縮效果展示
點擊下方的「上傳按鈕」,上傳 jpg 圖片後,會將圖片尺寸等比例縮小為 400px 寬,並壓縮為 80%,有效縮減檔案大小,又不降低圖片品質。
更多網頁開發工具: