File、Blob、Base64各种图片格式之间的转换

3,945 阅读4分钟

「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战

前言

对于前端的图片格式来说,比较常见的就是File、Blob、Base64着三种格式,在不同的场景需要不同的文件格式,他们之间的相互转换的方法就有必要记录一下。

各种图片格式的基本介绍

Blob

Blob 对象表示一个不可变、原始数据的类文件对象

在一个Blob对象中主要有两个属性,分别是:

  1. Blob.size 只读:

    Blob 对象中所包含数据的大小(字节)

  2. Blob.type 只读:

 一个字符串,表明该Blob对象所包含数据的 MIME 类型。如果类型未知,则该值为空字符串。

这里我们可以来看一下浏览器中输出的Blob对象:

e6b54189b07583fe7700463b3497000.png

可以看到是有着两个属性来描述这个Blob对象的。

Flie

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

File 接口也继承了 Blob 接口的属性,对象中一般有6个属性:

  1. File.lastModified 只读

    返回当前 File 对象所引用文件最后修改时间,自 UNIX 时间起始值(1970年1月1日 00:00:00 UTC)以来的毫秒数。

  2. File.lastModifiedDate 只读

    返回当前 File 对象所引用文件最后修改时间的 Date 对象。

  3. File.name 只读

    返回当前 File 对象所引用文件的名字。

  4. File.size 只读

    返回文件的大小。

  5. File.webkitRelativePath 只读

    返回 File 相关的 path 或 URL。

  1. File.type 只读

    返回文件的 多用途互联网邮件扩展类型(MIME Type)

然后我们也来看看浏览器中的File:

image.png

可以看到它的属性有和Blob一样的地方,只是在Blob的基础上做了扩展

Base64

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法

我们可以直接来看一个Base64格式的图片了解一下:

image.png 可以看到,Base64格式的图片以data开头,后面跟着图片类型和图片的基本数据。

各种图片格式之间的转换

Base64 to File(Blob)

/**
 * @param {*} dataURL base64编码数据
 * @param {*} filename 文件名称
 */
export function dataURLtoFile(dataurl, filename) {
    let arr = dataurl.split(','),
    let mime = arr[0].match(/:(.*?);/)[1], //mime类型 image/png
    let bstr = atob(arr[1]), //base64 解码
    let n = bstr.length,
    let u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, { type: mime });
     //return new Blob([a8arr], {type: mime});
}
  • 我们可以使用官方提供的new File或者new Blob的方法返回一个对应的实例,其中的参数type就是Base64的data后面的数据,做一下字符串分割就可以拿到,然后利用new Uint8Array循环计算出文件的大小和填充内容。
  • atob()函数能解码通过base-64编码的字符串数据。

File(Blob) to Base64

/**
* @param {*} file或者blob
* @param {*} callback
*/
function blobToBase64(blob, callback) {
    const reader = new FileReader();
    reader.addEventListener('load', ()=> {
        callback(reader.result);
    });
    reader.readAsDataURL(blob);
}

File(Blob) to Base64是通过FileReader这个对象上的load事件来实现转换,具体可以参考官方文档FileReader: load 由于读取是一个异步操作,所以我们可以在其中传入一个callback函数用来获取我们的结果,这里的reader作为一个FileReader的实例,在读取完成后会把数据存到result中:

image.png 我们就只要在callback中把数据传回去,在调用的时候就可以接收参数

image.png

Blob to File

Blob作为File的父类,在有些时候我们传输图片的格式只支持File文件,所以我们还是可以用File.File()方法将一个Blob对象转为File对象:

let files = new File([blob], 'xxx', { type: 'image/jpeg' })

参数接收一个Blob对象,输出文件名,和文件类型,这里要注意第一个参数[blob]的括号一定不能少,不然就会报错:

f894d915c1e2f4e42036bd2e72ae4ec.png

File to Blob

Flie对象转Blob的话,应该不需要多说了,从前的知识点可以看出,Blob对象中需要的属性File对象中都有,只需要new一个Blob对象然后去File对象中读取响应的值即可,这里就不在赘述。

总结

本文对常用的各种图片格式之间的转换方法和使用过程中遇到的问题做一个总结,也算是给自己做一个记录,方便之后遇到类似问题后的解决