JavaScript中文件流的處理場(chǎng)景及方法
常見(jiàn)場(chǎng)景
一、input框上傳文件
帶有 type="file"
的 <input> 元素允許用戶(hù)可以從他們的設(shè)備中選擇一個(gè)或多個(gè)文件。選擇后,這些文件可以使用提交表單的方式上傳到服務(wù)器上,或者通過(guò) Javascript 代碼和文件 API 對(duì)文件進(jìn)行操作。
如下代碼:
<input type="file" id="fileInput" /> <script> const input = document.getElementById("fileInput"); input.onchange = (e) => { const file = e.target.files[0]; console.log(file); }; </script>
如上圖,通過(guò)inpu框選擇文件上傳之后,我們可以獲取到我們上傳的文件對(duì)象,那么我們應(yīng)該怎樣將獲取到的文件對(duì)象更好的展示出來(lái)呢?
1、選擇圖片文件并在頁(yè)面上顯示
這種情況我們可以將獲取到的文件對(duì)象轉(zhuǎn)換為base64字符,再將其賦予img標(biāo)簽的src屬性即可,這里我們需要使用到FileReader
對(duì)象來(lái)進(jìn)行讀取。
FileReader
對(duì)象允許 Web 應(yīng)用程序異步讀取存儲(chǔ)在用戶(hù)計(jì)算機(jī)上的文件(或原始數(shù)據(jù)緩沖區(qū))的內(nèi)容,使用 File 或 Blob 對(duì)象指定要讀取的文件或數(shù)據(jù)。其中 File 對(duì)象可以是來(lái)自用戶(hù)在一個(gè)<input>元素上選擇文件后返回的FileList對(duì)象,也可以來(lái)自拖放操作生成的 DataTransfer對(duì)象,還可以是來(lái)自在一個(gè)HTMLCanvasElement上執(zhí)行
mozGetAsFile()
方法后返回結(jié)果。
詳細(xì)的介紹和更多的使用文檔都可以上MDN進(jìn)行查看,這里我也就不過(guò)多贅述了。
想要獲取文件的base64 編碼,我們可以使用readAsDataURL
方法來(lái)讀?。?/p>
readAsDataURL
方法會(huì)讀取指定的 Blob 或 File 對(duì)象。讀取操作完成的時(shí)候,readyState 會(huì)變成已完成DONE
,并觸發(fā) loadend 事件,同時(shí) result 屬性將包含一個(gè)data:
URL 格式的字符串(base64 編碼)以表示所讀取文件的內(nèi)容。
具體代碼如下:
<input type="file" id="fileInput" /> <img alt="" id="uploadImg" src="" style="width: 100px; height: 100px" /> <div id="uploadText"></div> <script> const input = document.getElementById("fileInput"); input.onchange = (e) => { const file = e.target.files[0]; const type = file.type.split("/")[0]; console.log("type", type); switch (type) { case "image": dealImg(file); break; }; function dealImg(file) { fileToBase64(file) .then((base64String) => { console.log("Base64:", base64String); const uploadImg = document.getElementById("uploadImg"); uploadImg.setAttribute("src", base64String); }) .catch((error) => { console.error("Error:", error); }); } function fileToBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => { resolve(reader.result); }; reader.onerror = (error) => { reject(error); }; reader.readAsDataURL(file); }); } </script>
2、選擇text文本文件并在頁(yè)面上顯示文件內(nèi)容
首先我們先創(chuàng)建一個(gè)txt文件,并寫(xiě)入一些內(nèi)容:
想要獲取文件的文本內(nèi)容,我們可以使用readAsText
方法來(lái)讀?。?/p>
readAsText
方法可以將 Blob 或者 File 對(duì)象轉(zhuǎn)根據(jù)特殊的編碼格式轉(zhuǎn)化為內(nèi)容 (字符串形式)
具體代碼如下:
<input type="file" id="fileInput" /> <img alt="" id="uploadImg" src="" style="width: 100px; height: 100px" /> <div id="uploadText"></div> <script> const input = document.getElementById("fileInput"); input.onchange = (e) => { const file = e.target.files[0]; const type = file.type.split("/")[0]; console.log("type", type); switch (type) { case "text": dealText(file); break; } }; function dealText(file) { readFile(file) .then((text) => { const uploadText = document.getElementById("uploadText"); uploadText.innerHTML = text; }) .catch((error) => { console.error("Error:", error); }); } function readFile(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (event) => { resolve(event.target.result); }; reader.onerror = (event) => { reject(error); }; reader.readAsText(file); // 使用readAsText方法讀取文件內(nèi)容 }); } </script>
二、將img標(biāo)簽圖片轉(zhuǎn)換為DataURL數(shù)據(jù)類(lèi)型或Blob數(shù)據(jù)類(lèi)型
1、將圖片轉(zhuǎn)換為 DataUR 數(shù)據(jù)類(lèi)型
我們首先獲取到 img 標(biāo)簽元素。然后創(chuàng)建一個(gè) canvas 元素,并獲取其 2D 上下文。根據(jù)圖像的寬度和高度設(shè)置 canvas 的寬度和高度。接著使用 drawImage
方法將 img 元素中的圖像繪制到 canvas 上。最后,使用 toDataURL
方法即可將 canvas 中的內(nèi)容轉(zhuǎn)換為 DataURL 數(shù)據(jù)類(lèi)型,具體代碼如下:
function imgToDataUrl() { const imgElement = document.getElementById("uploadImg"); // 獲取 img 標(biāo)簽元素 const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); canvas.width = imgElement.width; canvas.height = imgElement.height; // 在畫(huà)布上繪制圖片 context.drawImage(imgElement, 0, 0); // 將畫(huà)布內(nèi)容轉(zhuǎn)換為 DataURL const dataUrl = canvas.toDataURL("image/png"); console.log(dataUrl); // 輸出 DataURL 數(shù)據(jù) }
2、將圖片轉(zhuǎn)換為 Blob 數(shù)據(jù)類(lèi)型
前面canvas繪制圖片的步驟是一樣的,只是這里最后使用了canvas的toBlob
方法來(lái)進(jìn)行轉(zhuǎn)換,需要注意的是toBlob
方法中的幾個(gè)參數(shù):
toBlob(callback, type, quality)
callback
回調(diào)函數(shù),可獲得一個(gè)單獨(dú)的 Blob 對(duì)象參數(shù)。如果圖像未被成功創(chuàng)建,可能會(huì)獲得 null
值。
type
可選
DOMString 類(lèi)型,指定圖片格式,默認(rèn)格式(未指定或不支持)為 image/png
。
quality
可選
Number 類(lèi)型,值在 0 與 1 之間,當(dāng)請(qǐng)求圖片格式為 image/jpeg
或者 image/webp
時(shí)用來(lái)指定圖片展示質(zhì)量。如果這個(gè)參數(shù)的值不在指定類(lèi)型與范圍之內(nèi),則使用默認(rèn)值,其余參數(shù)將被忽略。
function imgToBlob() { const imgElement = document.getElementById("uploadImg"); // 獲取 img 標(biāo)簽元素 const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); canvas.width = imgElement.width; canvas.height = imgElement.height; // 在畫(huà)布上繪制圖片 context.drawImage(imgElement, 0, 0); // 將畫(huà)布內(nèi)容轉(zhuǎn)換為 Blob canvas.toBlob(function (blob) { // 處理獲取到的 Blob 數(shù)據(jù) console.log(blob); }, "image/png"); }
獲取到的Blob 數(shù)據(jù)如下:
三、圖片壓縮
我們可以使用JavaScrip對(duì)圖片進(jìn)行質(zhì)量壓縮來(lái)縮小圖片大小,具體使用到的方法是上面提到的toBlob(callback, type, quality)
,我們可以通過(guò)其第三個(gè)參數(shù)來(lái)對(duì)質(zhì)量進(jìn)行壓縮。
function doCompress() { imgToBlob((blob) => { console.log("原圖片", blob); compressImage(blob, Infinity, Infinity, 0.9).then((res) => { console.log("壓縮質(zhì)量為0.9得到圖片", res); }); }); } function compressImage(file, maxWidth, maxHeight, quality) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function (event) { const img = new Image(); img.src = event.target.result; img.onload = function () { let width = img.width; let height = img.height; if (width > maxWidth || height > maxHeight) { const ratio = Math.max(width / maxWidth, height / maxHeight); width /= ratio; height /= ratio; } const canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; const ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0, width, height); canvas.toBlob( function (blob) { resolve(blob); }, "image/jpeg", quality ); }; }; reader.onerror = function (error) { reject(error); }; }); } function imgToBlob(cb) { const imgElement = document.getElementById("uploadImg"); // 獲取 img 標(biāo)簽元素 const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); canvas.width = imgElement.width; canvas.height = imgElement.height; // 在畫(huà)布上繪制圖片 context.drawImage(imgElement, 0, 0); // 將畫(huà)布內(nèi)容轉(zhuǎn)換為 Blob canvas.toBlob(function (blob) { // 處理獲取到的 Blob 數(shù)據(jù) cb(blob); }, "image/png"); }
上面代碼定義了一個(gè)名為compressImage
的函數(shù),它接受四個(gè)參數(shù):file
(要壓縮的文件),maxWidth
(最大寬度),maxHeight
(最大高度)和quality
(圖像質(zhì)量,范圍從0到1)。
在函數(shù)內(nèi)部,我們首先使用FileReader
讀取文件,并將其轉(zhuǎn)換為Data URL。然后,我們創(chuàng)建一個(gè)Image
對(duì)象并將Data URL賦給它。在圖像加載完成后,我們根據(jù)指定的最大寬度和高度來(lái)調(diào)整圖像大小。
接下來(lái),我們使用<canvas>
元素創(chuàng)建一個(gè)畫(huà)布,并設(shè)置其寬度和高度。然后,我們?cè)诋?huà)布上通過(guò)drawImage
方法繪制圖像,將其縮放到適當(dāng)?shù)拇笮 ?/p>
最后,我們使用toBlob
方法將畫(huà)布內(nèi)容轉(zhuǎn)換為Blob對(duì)象,并將其以指定的JPEG格式和質(zhì)量解析。最終返回壓縮后的Blob對(duì)象。
具體效果如下:
四、圖片加水印
這個(gè)之前有單獨(dú)寫(xiě)了一篇文章,感興趣的同學(xué)可以到這里查看:JavaScript實(shí)現(xiàn)為圖片添加水印的方法詳解_javascript技巧_腳本之家 (jb51.net)
以上就是JavaScript中文件流處理場(chǎng)景及方法的詳細(xì)內(nèi)容,更多關(guān)于JavaScript文件流處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
BootStrap Validator 版本差異問(wèn)題導(dǎo)致的submitHandler失效問(wèn)題的解決方法
這篇文章主要介紹了BootStrap Validator 版本差異問(wèn)題導(dǎo)致的submitHandler失效問(wèn)題的解決方法,下面通過(guò)本文給大家詳細(xì)說(shuō)明一下,需要的朋友可以參考下2016-12-12js監(jiān)聽(tīng)元素是否出現(xiàn)在可視區(qū)域詳解(IntersectionObserver)
這篇文章主要給大家介紹了關(guān)于js監(jiān)聽(tīng)元素是否出現(xiàn)在可視區(qū)域(IntersectionObserver)的相關(guān)資料, IntersectionObserver是一個(gè)JavaScript API,用于監(jiān)測(cè)一個(gè)元素與其父元素或視窗的交叉狀態(tài),需要的朋友可以參考下2024-06-06前端實(shí)現(xiàn)監(jiān)控SDK的實(shí)戰(zhàn)指南
本文討論了前端監(jiān)控和數(shù)據(jù)統(tǒng)計(jì)的設(shè)計(jì)思路,包括錯(cuò)誤監(jiān)控、用戶(hù)行為日志、PV/UV統(tǒng)計(jì)等方面,介紹了數(shù)據(jù)采集、日志上報(bào)、日志查詢(xún)的流程,以及監(jiān)控錯(cuò)誤的類(lèi)型和用戶(hù)埋點(diǎn)統(tǒng)計(jì)的手段,同時(shí)提到了PV和UV的統(tǒng)計(jì)方法,需要的朋友可以參考下2024-10-10Javascript實(shí)現(xiàn)商品秒殺倒計(jì)時(shí)(時(shí)間與服務(wù)器時(shí)間同步)
在一些購(gòu)物商城經(jīng)??吹接泻芏嗌唐纷雒霘⒒顒?dòng),也就是倒計(jì)時(shí),本篇文章給大家介紹Javascript實(shí)現(xiàn)商品秒殺倒計(jì)時(shí)(時(shí)間與服務(wù)器時(shí)間同步),需要的朋友可以了解下2015-09-09[JS源碼]超長(zhǎng)文章自動(dòng)分頁(yè)(客戶(hù)端版)
[JS源碼]超長(zhǎng)文章自動(dòng)分頁(yè)(客戶(hù)端版)...2007-01-01javascript中的有名函數(shù)和無(wú)名函數(shù)
javascript中的有名函數(shù)和無(wú)名函數(shù)...2007-10-10基于JavaScript實(shí)現(xiàn)熔巖燈效果導(dǎo)航菜單
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)熔巖燈效果導(dǎo)航菜單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01