两种图片资源类型的 base64 格式转换

常用图片资源类型

我们项目里目前主要有三种图片资源类型

第三方图片资源、本地SVG、本地base64

这三种对应不同的使用场景:

  • 对于图片画质要求较高、图片内容较复杂的,一般都是将图片资源放到第三方图床上,页面展示通过加载远程地址的方式;
  • 小的 icon 图标,首选 SVG 格式,文件体积小,加载更快速。但是实现成本比较大,一般情况需要设计师的支持;
  • base64,某些特殊功能实现下需要的格式,不常见 ,但是有,比如页面保存图片功能。

base64 转换

对于新的图片,可以直接采用本地上传之后进行转换。

对于已有的图片或者接口返回的图片资源,大多是第三方资源,这种情况下将资源下载之后再进行转换。

本地选择图片转 base64

完成转换的关键点是借助 FileReader 读取图片数据和返回该图片的 Base64 字符串。

input 选择图片

支持多选

<input type="file" accept="*" id="imgInput" multiple />

选择图片之后可以得到它的 files 属性,值是数组类型。

var imgInput = document.getElementById('imgInput');
// 输入框值更改监听
imgInput.addEventListener('change', event => {
  imgFiles = imgInput.files;
});

FileReader 处理图片

前面得到的图片的 files 值是数组,所以转换时需要进行循环处理,逐个转换。

if (imgFiles) {
  for (let i = 0; i < imgFiles.length; i++) {
    let file = imgFiles[i];
    // 读取文件内容
    var reader = new FileReader();
    reader.onloadend = function (e) {
      base64List[i] = e.target.result;
      // 页面回显
      base64Show(base64List[i]);
    };
    // 将读取到的文件编码成DataURL 在Data URL协议中,图片被转换成base64编码的字符串形式
    reader.readAsDataURL(file);
  }
}

使用 FileReaderreadAsDataURL 方法读取文件之后,result 值会是 Base64 字符串。

result 值的获取,则是通过 FileReaderonloadend 事件,在文件读取结束之后,被包含在 ProgressEvent ******对象,在该对象的 target 属性下。

我把 ProgressEvent 的值打印出来:

两种图片资源类型的 base64 格式转换

知识点补充

FileReader.onloadend:处理loadend事件。该事件在读取操作结束时(要么成功,要么失败)触发。

FileReader.readAsDataURL():开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL 格式的 Base64 字符串以表示所读取文件的内容。

页面回显处理

在 div 标签下新增 textarea 标签,回显图片 base64 字符串值。

// 页面回显
function base64Show(base64Val) {
  let textarea = document.createElement('textarea');
  textarea.value = base64Val;
  base64.appendChild(textarea);
}

第三方图片资源转 base64

第三方图片资源,在获取图片的 base64 字符串之前,要先从远程将资源请求到本地。

这里我是借助 XMLHttpRequest 请求图片URL,获取图片数据:

function imgToBase64(imgUrl) {
  window.URL = window.URL || window.webkitURL;
  // 创建 XMLHttpRequest 对象
  var xhr = new XMLHttpRequest();
  // get请求,请求图片资源
  xhr.open('get', imgUrl, true);
  xhr.responseType = 'blob';
  xhr.onload = function () {
    // this指向xhr
    if (this.status == 200) {
      // 返回结果是 Blob 类型
      var blob = this.response;
      // 读取文件内容
      var reader = new FileReader();
      ......
      // 将读取到的文件编码成DataURL 在Data URL协议中,图片被转换成base64编码的字符串形式
      reader.readAsDataURL(blob);
    }
  };
  xhr.send();
}

open 方法,会初始化一个请求。

因为 FileReader.readAsDataURL指定了读取Blob类型数据,所以通过 xhr.responseType 定义响应类型为 blob。

请求完成之后会触发 onload 事件,这时便可以拿到响应的正文,响应正文存放在 response 属性中。因为前面设置了 responseType 的值为 blob,所以这里返回了 Blob 类型。

打印一下结果:

两种图片资源类型的 base64 格式转换

注:

1、open 方法只能在 JavaScript 代码中使用。

2、response中返回的类型为 ArrayBuffer、Blob、Document、JavaScript Object 或字符串中的一个。这取决于请求的 responseType 属性。

小课堂

小课堂会不定期出现,分享特定场景中遇到的问题,以及我的解决方案。(不过方案可能不是最佳或因人而异,主要用做抛砖引玉。)

警惕非技术舒适圈

最近我在三省吾身的时候,发现了一种状况,才猛地发现除了开发舒适圈,其实还有其他类型舒适圈。虽然对于开发者来说可能不太常见,但是会有一定程度上的影响,比如沟通舒适圈。

什么情况下会造成沟通舒适圈?

如果经常固定的和一组人一起工作,相互之间会形成一定度的默契感。

每次任务在相互配合时,无需过多言语,便可以顺利进行

会有哪些影响?

如果临时接到不熟悉的项目的时候,新接触的人,思维模式会和自己的认知产生偏差。可能会导致沟通时的观念障碍。

如果不能及时做出调整,可能会有一些负面影响,比如双方的无效沟通,会消耗更多的时间

需要怎么做?

有一点需要额外注意的是,转换固有思维,站在对方的角度,并不是潜意识中的「我要一味迁就对方」。

而是适当的研究对方对于开发技术的了解程度,尽可能用对方能理解的方式交换沟通的效率

也可以在发现沟通的差异点之后,提前和对方确定部分可以做统一意见的内容

总结

base64 转换的灵感来自七老《chatgpt,能帮我将html中的图片转为base64吗?》

因为我当时也在做一个功能需要把七牛云的资源转换成 base64,顺便把两种方式下的功能都实现了下。

捎带着熟悉了一下 FileReader 的相关知识点,温故而知新。

以上就是本次分享的内容。如果觉得有帮助,欢迎留言讨论、点赞 、收藏,持续产出技术分享。


我是 叶一一,非职业「传道授业解惑」的技术博主。「趣学前端」、「CSS畅想」系列作者。

华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。

欢迎技术或非技术问题的讨论。

本文正在参加「金石计划」

原文链接:https://juejin.cn/post/7215378495689080891 作者:叶一一

(0)
上一篇 2023年3月29日 下午4:43
下一篇 2023年3月29日 下午4:54

相关推荐

发表回复

登录后才能评论