前端文件数据格式那些事儿

2025-05-29 0 57

前言

前端文件数据格式那些事儿

Web 开发中,当我们处理文件时(创建,上传,下载),经常会遇到二进制数据。另一个典型的应用场景是图像处理。

在 JavaScript 中有很多种二进制数据格式,比如ArrayBuffer,Uint8Array,DataView,Blob,File 等等,不过 JavaScript 中的二进制数据是以非标准方式实现的。

下面我们来了解下这些数据格式及相互转换。

本文涉及到File,Blob,TypedArray,data url(Base64),blob url等等。

File

首先,我们还是拿前文的例子来看,显示用户选择的图片。

我们创建一个页面。提供选择图片功能。

  1. <!DOCTYPEhtml>
  2. <html>
  3. <head>
  4. <title>test</title>
  5. </head>
  6. <body>
  7. <inputtype="file"id="fileInput"name="选择图片"/>
  8. <divclass="wrap-image">
  9. <canvasid="canvas"></canvas>
  10. </div>
  11. <scripttype="text/javascript">
  12. </script>
  13. </body>
  14. </html>

选择图片后,需要将图片显示到canvas中,我们在上面的script标签中加入下面的代码:

  1. const fileInput = document.getElementById('fileInput')
  2. const canvas = document.getElementById('canvas')
  3. fileInput.addEventListener('change', (e) => {
  4. let img = new Image
  5. const file = e.target.files[0]
  6. img.src = URL.createObjectURL(file)
  7. img.onload = () => {
  8. canvas.width = img.width
  9. canvas.height = img.height
  10. const context = canvas.getContext('2d')
  11. context.drawImage(img, 0, 0)
  12. }
  13. }, false)

选择一张图片后,change事件中获取到选择的文件e.target.files[0]:

前端文件数据格式那些事儿

File 对象是特殊类型的 Blob,可以用在任意的 Blob 类型的 context 中。

比如 FileReader, URL.createObjectURL(), createImageBitmap(), 及 XMLHttpRequest.send() 都能处理 Blob 和 File。

File 接口也继承了 Blob 接口的属性。上图的Prototype展开可以看到继承自Blob:

前端文件数据格式那些事儿

上面是最常见的file获取方式————从<input type="file">中获取。

  1. new File(fileParts, fileName, [options])
  • fileParts —— Blob/BufferSource/String 类型值的数组
  • fileName —— 文件名字符串
  • options —— 可选对象

FileReader

FileReader 的用途是从 Blob(因此也从 File)对象中读取数据。

它使用事件来传递数据,因为从磁盘读取数据可能比较费时间。

可以读取为3种格式:

前端文件数据格式那些事儿

比如将 Blob 读取为 base64:

  1. const reader = new FileReader()
  2. reader.readAsDataURL(file) // 将 Blob 读取为 base64

使用时选择哪一种,要看如何使用数据。

读取过程中有下列事件:

1、loadstart: 开始加载

2、progress: 在读取过程中出现

3、load: 读取完成,没有 error

4、abort: 调用了 abort()取消操作

5、error: 出现 error

6、loadend: 读取完成,无论成功还是失败

使用最广泛的是load和error,比如下面的例子:

  1. <inputtype="file"onchange="readFile(this)">
  2. <script>
  3. constreadFile=(input)=>{
  4. constfile=input.files[0]
  5. constreader=newFileReader()
  6. reader.readAsText(file)
  7. reader.onload=()=>{
  8. console.log(reader.result)//结果
  9. }
  10. reader.onerror=()=>{
  11. console.log(reader.error)//error
  12. }
  13. }
  14. </script>

不过大多数情况下,我们不需要读取Blob,通过网络发送一个File很容易,像 XMLHttpRequest 或 fetch 等 API 本身就接受 File 对象。或者用URL.createObjectURL(file) 创建一个短的 url,并将其赋给 或 前端文件数据格式那些事儿

我们可以通过构造函数创建一个Blob:

  1. new Blob(blobParts, options)
  • blobParts是 Blob/BufferSource/String 类型的值的数组
  • options 可选对象:

type: Blob 类型,通常是 MIME 类型,例如 image/png

endings:是否转换换行符,使 Blob 对应于当前操作系统的换行符( 或 )。默认为 “transparent”(啥也不做),不过也可以是 “native”(转换)

比如从字符串创建 Blob:

  1. // 注意:第一个参数必须是一个数组 […]
  2. const blob = new Blob(['…'], {type: 'text/html'})

图片 to Blob

图像操作是通过canvas来实现的:

1、使用 canvas.drawImage 在 canvas 上绘制图像(绘制后可以做一些图像处理,比如旋转、裁剪等等);

2、调用 canvas 的 toBlob(callback, format, quality)方法 创建一个 Blob。

比如,在上面的context.drawImage(img, 0, 0);后,我们把canvas转成Blob:

  1. canvas.toBlob((blob) => {
  2. console.log('blob', blob)
  3. }, 'image/png')

前端文件数据格式那些事儿

或者,更喜欢同步的写法:

  1. img.onload = async () => {
  2. context.drawImage(img, 0, 0)
  3. const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png'))
  4. console.log('blob', blob)
  5. }

Blob to Base64

URL.createObjectURL 的一个替代方法是,将 Blob 转换为 base64。

base64编码将二进制数据表示为一个由 0 到 64 的 ASCII 码组成的字符串,非常安全且可读。

我们可以在 data-url 中使用base64编码,data-url就像下面这样:

  1. data:[][;base64],

我们可以像常规url一样使用data-url 。

比如一张支持alpha透明度的webp的图片:

  1. <imgsrc="data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==">

我们可以用 FileReader 将 Blob 转换为 base64:

  1. // img.src = URL.createObjectURL(file)
  2. const reader = new FileReader()
  3. reader.readAsDataURL(file) // 将 Blob 转换为 base64 并调用 onload
  4. reader.onload = () => {
  5. img.src = reader.result
  6. }

现在我们可以从Blob创建2种url,一种是blob url,一种是data url,下面我们对比下这2种方式:

前端文件数据格式那些事儿

所以要使用哪种url,需要具体情况再分析。

ArrayBuffer

基本的二进制对象 ArrayBuffer是对固定长度的连续内存空间的引用,是一个内存区域,一个原始的二进制数据。

我们可以这样创建一个长度为 16 的 buffer:

  1. let buffer = new ArrayBuffer(16); // 创建一个长度为 16 的 buffer
  • 注意:ArrayBuffer 和 Array 没有任何关系

我们可以通过 FileReader 的 readAsArrayBuffer 读取 Blob 的二进制数据:

  1. const reader = new FileReader()
  2. reader.readAsArrayBuffer(file)
  3. reader.onload = () => {
  4. const buffer = reader.result
  5. }

前端文件数据格式那些事儿

或者用Blob的arrayBuffer方法:

  1. const buffer = await file.arrayBuffer()

上面我们看到了Int8Array、Uint8Array、Int16Array,它们的通用术语是TypedArray,此外,还有其他的TypedArray。

前端文件数据格式那些事儿

总结

现在回顾一下:

1、<input type="file">是最常见的File获取方式;

2、File对象是特殊类型的 Blob;

3、Blob可以生成blob url;

4、FileReader可以读取Blob为3种格式,二进制格式的 ArrayBuffer,给定编码的字符串,base64编码的 data url;

5、blob url和data url都可以作为url使用;

6、Blob对象的arrayBuffer方法可以读取Blob的ArrayBuffer;

7、canvas.toBlob(callback, format, quality)可以把canvas读取为Blob;

下图可以很直观的看到它们之间的相关转换关系:

前端文件数据格式那些事儿

原文链接:https://www.toutiao.com/a7028839875885662757/

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 前端文件数据格式那些事儿 https://www.kuaiidc.com/91645.html

相关文章

发表评论
暂无评论