两种图片资源类型的 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);
}
}
使用 FileReader 的 readAsDataURL 方法读取文件之后,result 值会是 Base64 字符串。
result 值的获取,则是通过 FileReader 的 onloadend 事件,在文件读取结束之后,被包含在 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中返回的类型为 ArrayBuffer、Blob、Document、JavaScript Object 或字符串中的一个。这取决于请求的 responseType 属性。
小课堂
小课堂会不定期出现,分享特定场景中遇到的问题,以及我的解决方案。(不过方案可能不是最佳或因人而异,主要用做抛砖引玉。)
警惕非技术舒适圈
最近我在三省吾身的时候,发现了一种状况,才猛地发现除了开发舒适圈,其实还有其他类型舒适圈。虽然对于开发者来说可能不太常见,但是会有一定程度上的影响,比如沟通舒适圈。
什么情况下会造成沟通舒适圈?
如果经常固定的和一组人一起工作,相互之间会形成一定度的默契感。
每次任务在相互配合时,无需过多言语,便可以顺利进行。
会有哪些影响?
如果临时接到不熟悉的项目的时候,新接触的人,思维模式会和自己的认知产生偏差。可能会导致沟通时的观念障碍。
如果不能及时做出调整,可能会有一些负面影响,比如双方的无效沟通,会消耗更多的时间。
需要怎么做?
有一点需要额外注意的是,转换固有思维,站在对方的角度,并不是潜意识中的「我要一味迁就对方」。
而是适当的研究对方对于开发技术的了解程度,尽可能用对方能理解的方式交换沟通的效率。
也可以在发现沟通的差异点之后,提前和对方确定部分可以做统一意见的内容。
总结
base64 转换的灵感来自七老的 《chatgpt,能帮我将html中的图片转为base64吗?》
因为我当时也在做一个功能需要把七牛云的资源转换成 base64,顺便把两种方式下的功能都实现了下。
捎带着熟悉了一下 FileReader 的相关知识点,温故而知新。
作者:非职业「传道授业解惑」的开发者叶一一
简介:「趣学前端」、「CSS畅想」系列作者,华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)