jQuery – JavaScript – 教你如何製作圖片上傳前的預覽圖

* 如果您想要用套件可以來這篇 (2017/03/07更新)
目標
- 讓使用者在上傳圖片前先顯示在頁面,用來確定是不是要上傳的圖片。
- 透過前端技術完成,不使用網路傳輸到伺服器做縮圖後回傳到前端。
解決方法
使用 Web APIs 的 FileReader (檔案讀取器) 來達到。關於 FileReader 的用法,可參考說明。
線上測試
HTML
1 2 3 4 5 6 7 8 9 |
<form> <input type='file' class="upl"> <div> <img class="preview" style="max-width: 150px; max-height: 150px;"> <div class="size"></div> </div> </form> |
JavaScript/jQuery
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
$(function (){ function format_float(num, pos) { var size = Math.pow(10, pos); return Math.round(num * size) / size; } function preview(input) { if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function (e) { $('.preview').attr('src', e.target.result); var KB = format_float(e.total / 1024, 2); $('.size').text("檔案大小:" + KB + " KB"); } reader.readAsDataURL(input.files[0]); } } $("body").on("change", ".upl", function (){ preview(this); }) }) |
解說
當 input.upl[type=file] 發生改變的時候會觸發我們自訂的 preview 方法。
1 2 3 4 5 |
$("body").on("change", ".upl", function (){ preview(this); }) |
我們看 preview 方法怎麼寫
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/** * 預覽圖 * @param input 輸入 input[type=file] 的 this */ function preview(input) { // 若有選取檔案 if (input.files && input.files[0]) { // 建立一個物件,使用 Web APIs 的檔案讀取器(FileReader 物件) 來讀取使用者選取電腦中的檔案 var reader = new FileReader(); // 事先定義好,當讀取成功後會觸發的事情 reader.onload = function (e) { console.log(e); // 這裡看到的 e.target.result 物件,是使用者的檔案被 FileReader 轉換成 base64 的字串格式, // 在這裡我們選取圖檔,所以轉換出來的,會是如 『data:image/jpeg;base64,.....』這樣的字串樣式。 // 我們用它當作圖片路徑就對了。 $('.preview').attr('src', e.target.result); // 檔案大小,把 Bytes 轉換為 KB var KB = format_float(e.total / 1024, 2); $('.size').text("檔案大小:" + KB + " KB"); } // 因為上面定義好讀取成功的事情,所以這裡可以放心讀取檔案 reader.readAsDataURL(input.files[0]); } } |
其中要顯示的檔案大小,會須要做運算的轉換,我們額外包了一個 format_float 的方法
1 2 3 4 5 6 7 8 9 10 11 12 |
/** * 格式化 * @param num 要轉換的數字 * @param pos 指定小數第幾位做四捨五入 */ function format_float(num, pos) { var size = Math.pow(10, pos); return Math.round(num * size) / size; } |
如果須要多圖預覽,請參考進階的 下一篇文章。
這邊的範例比較簡單,只能做一張圖片的預覽。
easonchiu713
2016-04-24 - 00:33
你好我是正在學習jquery js的小朋友0.0
用了您的方法製作後,我為了控制preview image的樣式加了border-radius 可是它卻出現框框 不知道原因>”<?
是否可以向您請教。
謝謝!
http://easondesign.co/%E5%93%81%E5%91%B3%E7%B6%B2%E7%AB%99demo/userupload.html
jsn
2016-05-26 - 12:00
這部分屬於CSS的部分,可以網路上找找相關資料囉。這部分涉及CSS的一些理念~需要再透別教學了唷
easonchiu713
2016-04-24 - 01:20
你好0.0,已解決!雖然不知道為什麼這樣就解決了。
我原本把max-width 改成只有單純的width,
但是改回max 那個框框就不見了0.0..
jsn
2016-05-26 - 12:00
這部分屬於CSS的部分,可以網路上找找相關資料囉。這部分涉及CSS的一些理念~需要再透別教學了唷
openshop
2016-11-19 - 13:21
你好!我按照的方法加上了FileReader的圖片預覽
http://work.applework.com/index.php?route=product/product&product_id=43
可是上傳檔案的按鈕還是要用AjaxUpload選擇檔案
請問要如何修改才能變成送出呢?謝謝!
UM
2017-01-24 - 06:43
感謝 幫助很大 @@
JSN
2017-03-02 - 09:44
謝謝你,我很開心
Sherry
2017-04-06 - 11:50
非常感謝分享教學~ 幫助很大, 謝謝~
JSN
2017-04-06 - 11:58
覺得開心 😀
Majiko
2017-04-06 - 14:14
感謝分享教學!剛好是我需要的功能
是否能請教其他相關問題
上傳後的圖片檔名,有什麼方式可以取得以便於post到後台處理我表單的資料嗎?
JSN
2017-04-14 - 16:29
可以直接使用套件,從前端取得圖檔名稱喔
http://jsnwork.kiiuo.com/archives/2517/jquery-%E4%BD%BF%E7%94%A8%E5%A5%97%E4%BB%B6-file-preview-js-%E7%B0%A1%E5%96%AE%E9%A1%AF%E7%A4%BA%E9%A0%90%E8%A6%BD%E5%9C%96
vivian
2017-08-09 - 10:18
您好 使用您的方法可以成功的顯示
可是當我有好幾個上傳圖片的資料
縮圖就無法正常顯示
會一直抓取”最後一次上傳”的圖片