JavaScript中文件流的處理場景及方法
常見場景
一、input框上傳文件
帶有 type="file" 的 <input> 元素允許用戶可以從他們的設(shè)備中選擇一個或多個文件。選擇后,這些文件可以使用提交表單的方式上傳到服務(wù)器上,或者通過 Javascript 代碼和文件 API 對文件進(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>
如上圖,通過inpu框選擇文件上傳之后,我們可以獲取到我們上傳的文件對象,那么我們應(yīng)該怎樣將獲取到的文件對象更好的展示出來呢?
1、選擇圖片文件并在頁面上顯示
這種情況我們可以將獲取到的文件對象轉(zhuǎn)換為base64字符,再將其賦予img標(biāo)簽的src屬性即可,這里我們需要使用到FileReader對象來進(jìn)行讀取。
FileReader對象允許 Web 應(yīng)用程序異步讀取存儲在用戶計算機(jī)上的文件(或原始數(shù)據(jù)緩沖區(qū))的內(nèi)容,使用 File 或 Blob 對象指定要讀取的文件或數(shù)據(jù)。其中 File 對象可以是來自用戶在一個<input>元素上選擇文件后返回的FileList對象,也可以來自拖放操作生成的 DataTransfer對象,還可以是來自在一個HTMLCanvasElement上執(zhí)行
mozGetAsFile()方法后返回結(jié)果。
詳細(xì)的介紹和更多的使用文檔都可以上MDN進(jìn)行查看,這里我也就不過多贅述了。
想要獲取文件的base64 編碼,我們可以使用readAsDataURL 方法來讀?。?/p>
readAsDataURL方法會讀取指定的 Blob 或 File 對象。讀取操作完成的時候,readyState 會變成已完成DONE,并觸發(fā) loadend 事件,同時 result 屬性將包含一個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文本文件并在頁面上顯示文件內(nèi)容
首先我們先創(chuàng)建一個txt文件,并寫入一些內(nèi)容:

想要獲取文件的文本內(nèi)容,我們可以使用readAsText 方法來讀?。?/p>
readAsText方法可以將 Blob 或者 File 對象轉(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ù)類型或Blob數(shù)據(jù)類型
1、將圖片轉(zhuǎn)換為 DataUR 數(shù)據(jù)類型
我們首先獲取到 img 標(biāo)簽元素。然后創(chuàng)建一個 canvas 元素,并獲取其 2D 上下文。根據(jù)圖像的寬度和高度設(shè)置 canvas 的寬度和高度。接著使用 drawImage 方法將 img 元素中的圖像繪制到 canvas 上。最后,使用 toDataURL 方法即可將 canvas 中的內(nèi)容轉(zhuǎn)換為 DataURL 數(shù)據(jù)類型,具體代碼如下:
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;
// 在畫布上繪制圖片
context.drawImage(imgElement, 0, 0);
// 將畫布內(nèi)容轉(zhuǎn)換為 DataURL
const dataUrl = canvas.toDataURL("image/png");
console.log(dataUrl); // 輸出 DataURL 數(shù)據(jù)
}2、將圖片轉(zhuǎn)換為 Blob 數(shù)據(jù)類型
前面canvas繪制圖片的步驟是一樣的,只是這里最后使用了canvas的toBlob方法來進(jìn)行轉(zhuǎn)換,需要注意的是toBlob方法中的幾個參數(shù):
toBlob(callback, type, quality)
callback
回調(diào)函數(shù),可獲得一個單獨(dú)的 Blob 對象參數(shù)。如果圖像未被成功創(chuàng)建,可能會獲得 null 值。
type可選
DOMString 類型,指定圖片格式,默認(rèn)格式(未指定或不支持)為 image/png。
quality可選
Number 類型,值在 0 與 1 之間,當(dāng)請求圖片格式為 image/jpeg 或者 image/webp 時用來指定圖片展示質(zhì)量。如果這個參數(shù)的值不在指定類型與范圍之內(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;
// 在畫布上繪制圖片
context.drawImage(imgElement, 0, 0);
// 將畫布內(nèi)容轉(zhuǎn)換為 Blob
canvas.toBlob(function (blob) {
// 處理獲取到的 Blob 數(shù)據(jù)
console.log(blob);
}, "image/png");
}獲取到的Blob 數(shù)據(jù)如下:

三、圖片壓縮
我們可以使用JavaScrip對圖片進(jìn)行質(zhì)量壓縮來縮小圖片大小,具體使用到的方法是上面提到的toBlob(callback, type, quality),我們可以通過其第三個參數(shù)來對質(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;
// 在畫布上繪制圖片
context.drawImage(imgElement, 0, 0);
// 將畫布內(nèi)容轉(zhuǎn)換為 Blob
canvas.toBlob(function (blob) {
// 處理獲取到的 Blob 數(shù)據(jù)
cb(blob);
}, "image/png");
}上面代碼定義了一個名為compressImage的函數(shù),它接受四個參數(shù):file(要壓縮的文件),maxWidth(最大寬度),maxHeight(最大高度)和quality(圖像質(zhì)量,范圍從0到1)。
在函數(shù)內(nèi)部,我們首先使用FileReader讀取文件,并將其轉(zhuǎn)換為Data URL。然后,我們創(chuàng)建一個Image對象并將Data URL賦給它。在圖像加載完成后,我們根據(jù)指定的最大寬度和高度來調(diào)整圖像大小。
接下來,我們使用<canvas>元素創(chuàng)建一個畫布,并設(shè)置其寬度和高度。然后,我們在畫布上通過drawImage方法繪制圖像,將其縮放到適當(dāng)?shù)拇笮 ?/p>
最后,我們使用toBlob方法將畫布內(nèi)容轉(zhuǎn)換為Blob對象,并將其以指定的JPEG格式和質(zhì)量解析。最終返回壓縮后的Blob對象。
具體效果如下:



四、圖片加水印
這個之前有單獨(dú)寫了一篇文章,感興趣的同學(xué)可以到這里查看:JavaScript實(shí)現(xiàn)為圖片添加水印的方法詳解_javascript技巧_腳本之家 (jb51.net)
以上就是JavaScript中文件流處理場景及方法的詳細(xì)內(nèi)容,更多關(guān)于JavaScript文件流處理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
BootStrap Validator 版本差異問題導(dǎo)致的submitHandler失效問題的解決方法
這篇文章主要介紹了BootStrap Validator 版本差異問題導(dǎo)致的submitHandler失效問題的解決方法,下面通過本文給大家詳細(xì)說明一下,需要的朋友可以參考下2016-12-12
js監(jiān)聽元素是否出現(xiàn)在可視區(qū)域詳解(IntersectionObserver)
這篇文章主要給大家介紹了關(guān)于js監(jiān)聽元素是否出現(xiàn)在可視區(qū)域(IntersectionObserver)的相關(guān)資料, IntersectionObserver是一個JavaScript API,用于監(jiān)測一個元素與其父元素或視窗的交叉狀態(tài),需要的朋友可以參考下2024-06-06
前端實(shí)現(xiàn)監(jiān)控SDK的實(shí)戰(zhàn)指南
本文討論了前端監(jiān)控和數(shù)據(jù)統(tǒng)計的設(shè)計思路,包括錯誤監(jiān)控、用戶行為日志、PV/UV統(tǒng)計等方面,介紹了數(shù)據(jù)采集、日志上報、日志查詢的流程,以及監(jiān)控錯誤的類型和用戶埋點(diǎn)統(tǒng)計的手段,同時提到了PV和UV的統(tǒng)計方法,需要的朋友可以參考下2024-10-10
Javascript實(shí)現(xiàn)商品秒殺倒計時(時間與服務(wù)器時間同步)
在一些購物商城經(jīng)??吹接泻芏嗌唐纷雒霘⒒顒?,也就是倒計時,本篇文章給大家介紹Javascript實(shí)現(xiàn)商品秒殺倒計時(時間與服務(wù)器時間同步),需要的朋友可以了解下2015-09-09
javascript中的有名函數(shù)和無名函數(shù)
javascript中的有名函數(shù)和無名函數(shù)...2007-10-10
基于JavaScript實(shí)現(xiàn)熔巖燈效果導(dǎo)航菜單
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)熔巖燈效果導(dǎo)航菜單,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01

