JavaScript中文件流的处理场景及方法
作者:JYeontu
常见场景
一、input框上传文件
带有 type="file"
的 <input> 元素允许用户可以从他们的设备中选择一个或多个文件。选择后,这些文件可以使用提交表单的方式上传到服务器上,或者通过 Javascript 代码和文件 API 对文件进行操作。
如下代码:
<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框选择文件上传之后,我们可以获取到我们上传的文件对象,那么我们应该怎样将获取到的文件对象更好的展示出来呢?
1、选择图片文件并在页面上显示
这种情况我们可以将获取到的文件对象转换为base64字符,再将其赋予img标签的src属性即可,这里我们需要使用到FileReader
对象来进行读取。
FileReader
对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。其中 File 对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行
mozGetAsFile()
方法后返回结果。
详细的介绍和更多的使用文档都可以上MDN进行查看,这里我也就不过多赘述了。
想要获取文件的base64 编码,我们可以使用readAsDataURL
方法来读取:
readAsDataURL
方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE
,并触发 loadend 事件,同时 result 属性将包含一个data:
URL 格式的字符串(base64 编码)以表示所读取文件的内容。
具体代码如下:
<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文本文件并在页面上显示文件内容
首先我们先创建一个txt文件,并写入一些内容:
想要获取文件的文本内容,我们可以使用readAsText
方法来读取:
readAsText
方法可以将 Blob 或者 File 对象转根据特殊的编码格式转化为内容 (字符串形式)
具体代码如下:
<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方法读取文件内容 }); } </script>
二、将img标签图片转换为DataURL数据类型或Blob数据类型
1、将图片转换为 DataUR 数据类型
我们首先获取到 img 标签元素。然后创建一个 canvas 元素,并获取其 2D 上下文。根据图像的宽度和高度设置 canvas 的宽度和高度。接着使用 drawImage
方法将 img 元素中的图像绘制到 canvas 上。最后,使用 toDataURL
方法即可将 canvas 中的内容转换为 DataURL 数据类型,具体代码如下:
function imgToDataUrl() { const imgElement = document.getElementById("uploadImg"); // 获取 img 标签元素 const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); canvas.width = imgElement.width; canvas.height = imgElement.height; // 在画布上绘制图片 context.drawImage(imgElement, 0, 0); // 将画布内容转换为 DataURL const dataUrl = canvas.toDataURL("image/png"); console.log(dataUrl); // 输出 DataURL 数据 }
2、将图片转换为 Blob 数据类型
前面canvas绘制图片的步骤是一样的,只是这里最后使用了canvas的toBlob
方法来进行转换,需要注意的是toBlob
方法中的几个参数:
toBlob(callback, type, quality)
callback
回调函数,可获得一个单独的 Blob 对象参数。如果图像未被成功创建,可能会获得 null
值。
type
可选
DOMString 类型,指定图片格式,默认格式(未指定或不支持)为 image/png
。
quality
可选
Number 类型,值在 0 与 1 之间,当请求图片格式为 image/jpeg
或者 image/webp
时用来指定图片展示质量。如果这个参数的值不在指定类型与范围之内,则使用默认值,其余参数将被忽略。
function imgToBlob() { const imgElement = document.getElementById("uploadImg"); // 获取 img 标签元素 const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); canvas.width = imgElement.width; canvas.height = imgElement.height; // 在画布上绘制图片 context.drawImage(imgElement, 0, 0); // 将画布内容转换为 Blob canvas.toBlob(function (blob) { // 处理获取到的 Blob 数据 console.log(blob); }, "image/png"); }
获取到的Blob 数据如下:
三、图片压缩
我们可以使用JavaScrip对图片进行质量压缩来缩小图片大小,具体使用到的方法是上面提到的toBlob(callback, type, quality)
,我们可以通过其第三个参数来对质量进行压缩。
function doCompress() { imgToBlob((blob) => { console.log("原图片", blob); compressImage(blob, Infinity, Infinity, 0.9).then((res) => { console.log("压缩质量为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 标签元素 const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); canvas.width = imgElement.width; canvas.height = imgElement.height; // 在画布上绘制图片 context.drawImage(imgElement, 0, 0); // 将画布内容转换为 Blob canvas.toBlob(function (blob) { // 处理获取到的 Blob 数据 cb(blob); }, "image/png"); }
上面代码定义了一个名为compressImage
的函数,它接受四个参数:file
(要压缩的文件),maxWidth
(最大宽度),maxHeight
(最大高度)和quality
(图像质量,范围从0到1)。
在函数内部,我们首先使用FileReader
读取文件,并将其转换为Data URL。然后,我们创建一个Image
对象并将Data URL赋给它。在图像加载完成后,我们根据指定的最大宽度和高度来调整图像大小。
接下来,我们使用<canvas>
元素创建一个画布,并设置其宽度和高度。然后,我们在画布上通过drawImage
方法绘制图像,将其缩放到适当的大小。
最后,我们使用toBlob
方法将画布内容转换为Blob对象,并将其以指定的JPEG格式和质量解析。最终返回压缩后的Blob对象。
具体效果如下:
四、图片加水印
这个之前有单独写了一篇文章,感兴趣的同学可以到这里查看:JavaScript实现为图片添加水印的方法详解_javascript技巧_脚本之家 (jb51.net)
以上就是JavaScript中文件流处理场景及方法的详细内容,更多关于JavaScript文件流处理的资料请关注脚本之家其它相关文章!