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

举报
叶一一 发表于 2023/08/27 20:50:51 2023/08/27
【摘要】 常用图片资源类型我们项目里目前主要有三种图片资源类型第三方图片资源、本地SVG、本地base64这三种对应不同的使用场景:对于图片画质要求较高、图片内容较复杂的,一般都是将图片资源放到第三方图床上,页面展示通过加载远程地址的方式;小的 icon 图标,首选 SVG 格式,文件体积小,加载更快速。但是实现成本比较大,一般情况需要设计师的支持;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 的值打印出来:

知识点补充

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 类型。

打印一下结果:

注:

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

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


小课堂

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

警惕非技术舒适圈

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

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

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

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

会有哪些影响?

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

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

需要怎么做?

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

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

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

总结

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

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

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


作者:非职业「传道授业解惑」的开发者叶一一
简介:「趣学前端」、「CSS畅想」系列作者,华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。