整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          10行JavaScript代碼完成圖片的上傳預覽

          擊右上方紅色按鈕關注“web秀”,讓你真正秀起來

          前言

          冬至,希望大家都可以有餃子和湯圓吃,主要是能和自己家人愛人一起吃個飯。

          下面進入主題,用原生JS給擼個圖片上傳,預覽的小示例,希望對大家有所幫助。

          示例

          function fChange() { 
           let file = document.getElementById('file'); 
           // 輸出已經選擇圖片名字 
           console.log(file.value); 
           // 輸出已經選擇的圖片對象 
           console.log(file.files[0]); 
          } 
          ... 
          <input type="file" id="file" onchange="fChange()">
          

          10行JavaScript代碼完成圖片的上傳預覽

          我們怎么把圖片對象渲染到頁面了?達到可以預覽的目的?

          // file 轉 blob對象 
          let bold = window.URL.createObjectURL(file.files[0]); 
          console.log('bold==>'+bold); 
           
          let boldImg = document.getElementById('bold'); 
          boldImg.src = bold; 
           
          // file 轉 base64 
          let base64Img = document.getElementById('base64'); 
          var reader = new FileReader(); 
          reader.readAsDataURL(file.files[0]); 
          reader.onload = function (e) { 
           console.log('base64==>'+this.result); 
           base64Img.src = this.result; 
          }
          

          10行JavaScript代碼完成圖片的上傳預覽

          10行JavaScript代碼完成圖片的上傳預覽

          這樣看blob對象和base64都可以預覽圖片,但是blob對象僅僅是當次緩存,如果刷新,你重新把之前轉的字符串放到src是不可以預覽的,當時base64是可以的。所以存庫的時候不僅可以圖片路徑,還可以直接存base64(base64很占用數據庫空間,文件越大,base64字符串越大)

          優化

          下面我們對上面示例做優化,可以上傳多張圖片并預覽,美化界面。

          10行JavaScript代碼完成圖片的上傳預覽

          10行JavaScript代碼完成圖片的上傳預覽

          <div id="img-pre"> 
          </div> 
          <div id="add-pic"> 
           <input type="file" id="up-file" onchange="fChange()"> 
          </div>
          

          css樣式

          #add-pic{ 
           width: 100px; 
           height: 100px; 
           background: url('./add-pic.png') 
          } 
          #add-pic input{ 
           width: 100%; 
           height: 100%; 
           display: none; 
          } 
          #img-pre:after{ 
           display: block; 
           content: ''; 
           clear: both; 
          } 
          #img-pre img{ 
           float: left; 
           width: 100px; 
           height: 100px; 
           margin-right: 10px; 
          }
          

          javascript

          let addPic = document.getElementById('add-pic'), upFile = document.getElementById('up-file'); 
          // 監聽圖片點擊,從而觸發input file的點擊事件 
          addPic.addEventListener('click', function(){ 
           upFile.click(); 
          }) 
          function fChange() { 
           let file = document.getElementById('up-file'); 
           let imgPre = document.getElementById('img-pre'); 
           
           // file 轉 blob對象 
           let bold = window.URL.createObjectURL(file.files[0]); 
           
           // 創建img元素,并添加到img-pre元素里 
           var img = document.createElement("img"); 
           img.setAttribute("src", bold); 
           imgPre.appendChild(img); 
          }
          

          主要是通過css隱藏掉input file選擇文件按鈕,然后用+號圖片點擊事件來觸發input file的點擊事件,達到能選擇圖片的目的。

          公告

          喜歡小編的點擊關注,了解更多知識!

          源碼地址請點擊下方“了解更多”

          文轉自:掘金 作者:chess

          前言

          本文講的圖片上傳,主要是針對上傳頭像的。大家都知道,上傳頭像一般都會分成以下 4 個步驟:

          選擇圖片 -> 預覽圖片 -> 裁剪圖片 -> 上傳圖片

          接下來,就詳細的介紹每個步驟具體實現。

          一、選擇圖片

          選擇圖片有什么好講的呢?不就一個 input[type=file] ,然后點擊就可以了嗎?確實是這樣的,但是,我們想要做得更加的友好一些,比如需要過濾掉非圖片文件, 或只允許從攝像頭拍照獲取圖片等,還是需要進行一些簡單配置的。

          下面就先來看看最簡單的選擇圖片:

          這時候,點擊這個 input , 在 iOS 手機的顯示如下:

          其中的 “瀏覽” 選項,可以查看到非圖片類型的文件,這并不是我們想要的結果,畢竟我們只想要圖片類型。可以通過 accept 屬性來實現,如下:

          這樣就可以過濾掉非圖片類型了。但是圖片的類型可能也太多了, 有些可能服務器不支持,所以,如果想保守一些,只允許 jpg 和 png 類型,可以寫成這樣:

          或:

          OK, 過濾非圖片的需求搞定了。但是有時候 ,產品還要求只能從攝像頭采集圖片,比如需要上傳證件照,防止從網上隨便找別人的證件上傳,那capture 屬性就可以派上用場了:

          這時候,就不能從文件系統中選擇照片了,只能從攝像頭采集。到了這一步,可能覺得很完美了,但是還有個問題,可能有些變態產品要求默認打開前置攝像頭采集圖片,比如就是想要你的自拍照片。 capture 默認調用的是后置攝像頭。默認啟用前置攝像頭可以設置 capture="user" ,如下:

          好啦,關于選擇圖片的就講么這么多了,有個注意的地方是,可能有些配置在兼容性上會有一些問題,所以需要在不同的機型上測試一下看看效果。

          下面再來談談預覽圖片的實現。

          二、預覽圖片

          在遠古時代,前端并沒有預覽圖片的方法。當時的做法時,用戶選擇圖片之后,立刻把圖片上傳到服務器,然后服務器返回遠程圖片的 url 給前端顯示。這種方法略顯麻煩,而且會浪費用戶的流量,因為用戶可能還沒有確定要上傳,你卻已經上傳了。幸好,遠古時代已經離我們遠去了,現代瀏覽器已經實現了前端預覽圖片的功能。常用的方法有兩個,分別是 URL.createObjectURL() 和 FileReader 。雖然他們目前均處在 w3c 規范中的 Working Draft 階段, 但是大多數的現代瀏覽器都已經良好的支持了。 下面就介紹一下如何使用這兩個方法。

          1. 使用 URL.createObjectURL 預覽

          URL.createObjectURL() 靜態方法會創建一個 DOMString,其中包含一個表示參數中給出的對象的 URL。這個 URL 的生命周期和創建它的窗口中的 document 綁定。這個新的URL 對象表示指定的 File 對象或 Blob 對象。用法用下:

          objectURL = URL.createObjectURL(object);

          其中,object 參數指 用于創建 URL 的 File 對象、Blob 對象或者 MediaSource 對象。

          對于我們的 input[type=file] 而言, input.files[0] 可以獲取到當前選中文件的 File 對象。示例代碼如下:

          具體用法可以參考 MDN上的 URL.createObjectURL(),

          2. 使用 FileReader 預覽

          FileReader 對象允許Web應用程序異步讀取存儲在用戶計算機上的文件(或原始數據緩沖區)的內容,使用 File 或 Blob 對象指定要讀取的文件或數據。同理的,我們也可以通過 input.files[0] 獲取到當前選中的圖片的 File 對象。

          特別注意,FileReader 和 是異步讀取文件或數據的!

          下面是使用 FileReader 預覽圖片的示例:

          會發現, FileReader 會相對復雜一些.

          更多關于 FileReader 的用法 ,可以參考 MDN 文檔 FileReader

          3.兩種方法的對比

          我個人更加傾向于使用 URL.createObjectURL() 。主要原先它的 API 簡潔,同步讀取,并且他返回的是一個 URL ,比 FileReaer 返回的base64 更加精簡。兼容性上,兩者都差不多,都是在 WD 的階段。性能上的對比, 在 chrome 上, 選擇了一張 2M 的圖片, URL.createObjectURL() 用時是 0 , 而 FileReader 用時 20ms 左右。 0 感覺不太合理,雖然這個方法立刻就會返回一個 URL ,但是我猜測實際上這個 URL 指定的內容還沒有生成好,應該是異步生成的,然后才渲染出來的。所以并沒有很好的辦法來對比他們的性能。

          如果想要學習更多關于圖片預覽,可以閱讀以下兩篇文章:

        1. 使用FileReader實現前端圖片預覽
        2. js圖片/視頻預覽 - URL.createObjectURL()
        3. 三、裁剪圖片

          關于圖片的裁剪,很自然的會想到使用 canvas ,確實是要通過 canvas, 但是如果全部我們自己來實現,可能需要做比較多的工作,所以為了省力,我們可以站在巨人的肩膀上。比較優秀的圖片裁剪庫是 cropperjs , 該庫可以對圖片進行縮放、移動和旋轉。

          cropperjs 的詳細配置這里就不展開了 ,需要的可以自己去看文檔就好。下面我們就以這個庫為基礎,實現一個裁剪人臉的例子:

          效果圖如下:

          四、上傳

          前面的操作已經完成了圖片上傳前的準備,包括選擇圖片、預覽圖片、編輯圖片等,那接下來就可以上傳圖片了。上面的例子中,使用了 cropperInstance.getCroppedCanvas() 方法來獲取到對應的 canvas 對象 。有了 canvas 對象就好辦了,因為 canvas.toBlob() 方法可以取得相應的 Blob 對象,然后,我們就可以把這個 Blob 對象添加到 FromData 進行無刷新的提交了。大概的代碼如下:

          這段代碼并不能真正執行,因為我們還沒有對應的后端服務器。如果想要嘗試上傳圖片的朋友,可以參考一下這篇文章 寫給新手前端的各種文件上傳攻略,從小圖片到大文件斷點續傳,由于篇幅原因,這里就不展開啦。

          五、最后

          關于圖片上傳的介紹,差不多不到些結束了。但是之前在 iPhone 和 小米 手機上,遇到一個奇怪的問題: 就是我使用前置攝像頭自拍出來的照片,選擇之后 ,會自逆時針旋轉 90 度,比如像下圖:

          拍照的時候明明就是正著拍的,為什么預覽就會變成橫著了呢?當時第一次遇到這個問題的時候,也覺得好奇怪。后來查了一下,得知這是因為拍照時,相機都會記錄拍照的角度信息,可能 iPhone 前置攝像頭記錄的角度信息和其他的有點不一樣,而 iPhone 自己的相冊在瀏覽照片時,自動糾正了角度 ,而瀏覽器卻沒有糾正,所以才會出現這個旋轉。

          為了解決這個問題,需要使用 EXIF 這個庫來處理。

          我剛剛試了一下,發現我的 iPhone 現在竟然不會有這個問題了,大概是半年前,當時在做一個需求時,自拍的圖片會發生這種旋轉,有可能是 iOS 系統升級后, 已經修復了這個問題。而現在身邊又沒有小米手機, 所以也不好復現。還好,當時我保存了一張會自動旋轉的圖片。

          圖片下載后,用電腦的圖片查看器打開是正常的,但是,在瀏覽器中,選擇這個圖片后,使用 URL.createObjectURL() 或 FileReader 來預覽就會發生旋轉。甚至直接 img 標簽引入也會逆時針旋轉了 90 度,比如:

          效果如下:

          下面就以這張圖片為例,介紹一下如何使用 EXIF 來檢測圖片角度。關于 EXIF 的詳細用法大家可以到 github 的主頁上查看 github.com/exif-js/exi…

          上面代碼的輸出 allMetaData.Orientation 的結果為 6 , 那 6 到底是什么意思呢? 可以參考這個篇文章 Exif Orientation Tag 里面有個表格:

          如果這個表格看不太懂,再參考一下這篇文章 JPEG Orientation,里有個圖:

          可以看出,攝像頭信息是逆時針旋轉了 90 度。那要怎么糾正呢?可以使用 CSS 的 transfrom: rotate(-90deg) 順時針旋轉 90 度抵消掉這個角度就好。

          事實上, CropperJS 也會檢測圖片的 EXIF 信息,并且會自動糾正角度的,詳情參考 github.com/fengyuanche… 這里也提到了,但只支持讀取 jpg 圖片的 EXIF 信息,而我們這張圖片是 PNG 所以并不支持。

          有個 CSS 屬性叫做 image-orientation , 它有個值叫做 from-image , 就是使用圖片的 EXIF 數據來旋轉的。可惜,目前 chrome 不支持該屬性。有興趣的可以了解一下。

          結語

          好啦,就先寫到這里啦,有問題的歡迎在評論區交流哈~

          想了解更多前端知識歡迎評論區留言或私信我!

          歡迎關注公眾號:fkdcxy 瘋狂的程序員丶 獲取更多前端教程!

          一步寫入input

           .uploadWrap{
           font-size: 14px;
           line-height: 24px;
           cursor: pointer;
           height: 36px;
           width: 118px;
           margin-right: 6px;
           margin-left: 28px;
           position: relative;
           }
          
           .ph08{
           opacity: 0; //如果自定義上傳按鈕一般都會這樣設置
           height: 36px;
           width: 118px;
           position: absolute;
           top: 0;
           left: 0;
           }
          
          <div class="poster" id="poster"> </div>//圖片顯示dom
          
          
          <button class="uploadWrap defaultBtn_low_short_noBg">
           <input type="file" name="file0" id="file0" multiple="" class="ph08">
           上傳海報
           </button>
          

          第二步js獲取上傳圖片路徑

           //處理圖片路徑
          function getObjectURL(file) {
           var url = null;
           if (window.createObjectURL != undefined) { // basic
           url = window.createObjectURL(file);
           } else if (window.URL != undefined) { // mozilla(firefox)
           url = window.URL.createObjectURL(file);
           } else if (window.webkitURL != undefined) { // webkit or chrome
           url = window.webkitURL.createObjectURL(file);
           }
           return url;
           }
          
          $("#file0").change(function(){
           if (this.files && this.files[0]){
           var filePath = $('#file0').val().toLowerCase().split(".");
           var fileType = filePath[filePath.length - 1]; //獲取圖片格式
           if(fileType=='zip'||fileType=='rar'||fileType=='html'){
           alert("請上傳圖片格式");
           return false;
           }
           var objUrl = getObjectURL(this.files[0]);
           if(objUrl){
           console.log(objUrl);
           $("#poster").css("background-image","url("+objUrl+")");
           $("#file0").click(function(e){
           $("#poster").css("background-image","url("+objUrl+")");
           })
           }
           }
           })
          
          

          這樣獲取到圖片路徑直接放入到你想要顯示的dom就可以


          主站蜘蛛池模板: 国产一区二区三区精品视频| 日本视频一区在线观看免费 | 中文字幕VA一区二区三区| 熟女大屁股白浆一区二区| 免费无码VA一区二区三区| 香蕉久久AⅤ一区二区三区| 日韩精品一区二区三区中文精品 | 国内精品一区二区三区在线观看 | 久久国产香蕉一区精品 | 国产一区三区三区| 日韩在线一区二区三区视频| 无码精品黑人一区二区三区 | 国产一区二区免费视频| www.亚洲一区| 国产一区二区三区电影| bt7086福利一区国产| 亚洲国产精品自在线一区二区 | 久99精品视频在线观看婷亚洲片国产一区一级在线 | 亚洲福利视频一区| 国产在线精品一区免费香蕉 | 一本一道波多野结衣一区| 搡老熟女老女人一区二区| 精品国产免费一区二区三区香蕉| 视频在线一区二区三区| 日本在线视频一区二区三区| 日韩成人无码一区二区三区 | 精品爆乳一区二区三区无码av| 国产精品区一区二区三在线播放 | 日韩在线一区高清在线| 尤物精品视频一区二区三区| 亚洲欧洲日韩国产一区二区三区| 亚洲一区二区电影| 久久久av波多野一区二区| 亚洲无删减国产精品一区| 色国产精品一区在线观看| 精品无码人妻一区二区三区 | 免费一区二区无码东京热| 东京热人妻无码一区二区av| 狠狠色成人一区二区三区| 国产一区二区三区不卡AV| 国产精品熟女一区二区|