URL.createObjectURL(blob:Blob)
URL.revokeObjectURL(objectURL)
扫描二维码关注公众号,回复:
12717632 查看本文章
![](/qrcode.jpg)
图片上传下载与压缩
Blob
Blob
(Binary Large Object) 对象代表了一段二进制数据,提供了一系列操作接口。其他操作二进制数据的API(如 File
对象),都是建立在 Blob
对象基础上的,继承了它的属性和方法。
创建 Blob 实例对象
Blob
构造函数,接受两个参数。第一个参数是一个包含实际数据的数组,这个数组中的元素可以为 DOMString
,或者 ArrayBuffer
,第二个参数是数据的类型,这两个参数都不是必需的。
var blob = new Blob(["Hello World"], {type: 'text/html'});
Blob 对象的属性
- size属性
var blob = new Blob(["Hello World"], {type: 'text/html'});
console.log(blob.size) // 11
- type属性
var blob = new Blob(["Hello World"], {type: 'text/html'});
console.log(blob.type) // text/html
Blob实例
// 创建Blob实例对象,通过超链接下载文件
var blob = new Blob(["Hello World"], {type: 'text/html'});
var elink = document.createElement("a");
elink.href = window.URL.createObjectURL(blob);
elink.download = "hello-world.txt";
elink.textContent = "Download File!";
document.body.appendChild(elink);
File
JavaScript中,File继承自Blob。即 File extends Blob; 最常使用场景是通过 <input type="file"> 上传文件时。File实例对象有三个常用的属性:name(文件名) size(文件大小,单位为字节) type(文件的 MIME 类型)
<html>
<body>
<input type="file" id="fileInput" name="file" multiple="multiple" />
</body>
</html>
<script>
var fileList = [] // 文件数组集合
var fileInput = document.getElementById("fileInput")
fileInput.addEventListener("change", function (event) {
var file = fileInput.files[0] // 获取文件信息 File实例对象
fileList.push(file)
console.log(file)
})
</script>
URL
最常用的场景是将二进制文件转为一个 URL
,这个 URL
可以放置于任何通常可以放置 URL
的地方,比如 img
标签的 src
属性。
URL.createObjectURL(blob:Blob)
<html>
<body>
<input type="file" id="fileInput" name="file" multiple="multiple" />
</body>
</html>
<script>
var fileList = []; // 文件数组集合
var fileInput = document.getElementById("fileInput")
fileInput.addEventListener("change", function (event) {
var file = fileInput.files[0] // File
fileList.push(file)
// URL.createObjectURL(Blob: blob) 二进制数据转url
var imgUrl = URL.createObjectURL(file) // file是File实例,File继承自Blob,因此file也是Blob的一个实例
var img = new Image() // 创建Image实例对象
img.src = imgUrl
img.onload = () => {
document.body.appendChild(img)
}
});
</script>
URL.revokeObjectURL(objectURL)
移除转化的url,即释放url。
<html>
<body>
<input type="file" id="fileInput" name="file" multiple="multiple" />
</body>
</html>
<script>
var fileList = []; // 文件数组集合
var fileInput = document.getElementById("fileInput")
fileInput.addEventListener("change", function (event) {
var file = fileInput.files[0] // File
fileList.push(file)
// 下载图片
var elink = document.createElement('a')
var downloadUrl = URL.createObjectURL(file)
elink.href = downloadUrl
elink.download = file.name // 设置文件的文件名
elink.textContent = ''
document.body.appendChild(elink)
elink.click()
URL.revokeObjectURL(downloadUrl) // 移除 url
document.body.removeChild(elink)
})
</script>
FileReader
Blob
对象和File对象只是存放二进制数据的容器,本身并不能操作二进制。FileReader
对象就是专门操作二进制数据的。
创建FileReader实例对象
var fileReader = new FileReader()
常用属性
- result:文件的内容。该属性仅在读取操作完成后才有效。
常用事件
- onload:处理
load
事件。该事件在读取操作完成时触发。
常用方法
- readAsDataURL():开始读取指定的
Blob
中的内容。一旦完成,result
属性中将包含一个data:URL
格式的字符串以表示所读取文件的内容;此时result
属性可以充当url,效果类似于URL.createObjectURL(Blob: blob)生成的url,当两种url是不一样的。
<html>
<body>
<input type="file" id="fileInput" name="file" multiple="multiple" />
</body>
</html>
<script>
var fileList = []; // 文件数组集合
var fileInput = document.getElementById("fileInput")
fileInput.addEventListener("change", function (event) {
var file = fileInput.files[0] // File
fileList.push(file)
// FileReader
var fileReader = new FileReader()
fileReader.readAsDataURL(file) // 读文件,读取完后,文件内容会以 data: URL 形式放到 result 属性中
fileReader.onload = () => { // onload : 文件读取完后
// 显示图片
var img = new Image() // Image对象
img.src = fileReader.result // 设置图片src为fileReader的result属性
img.onload = () => {
document.body.appendChild(img)
}
}
})
</script>
图片上传
图片直接上传
拿到File实例对象,直接上传。
<template>
<div class="about">
<input
type="file"
id="fileInput"
name="file"
multiple="multiple"
@change="uploadImg"
/>
</div>
</template>
<script>
import { defineComponent, getCurrentInstance } from "vue";
export default defineComponent({
name: "About",
setup() {
const { proxy } = getCurrentInstance();
function uploadImg() {
var fileInput = document.getElementById("fileInput");
var file = fileInput.files[0];
var formData = new FormData();
formData.append("imgFile", file);
proxy.$axios
.post("/avatar/upload", formData) // 网络请求
.then((result) => {
console.log(result);
})
.catch(() => {
/* */
})
}
return {
uploadImg
}
}
});
</script>
图片压缩后上传
图片压缩后,可以再转为File实例对象,然后调接口上传。
<template>
<div class="about">
<input
type="file"
id="fileInput"
name="file"
multiple="multiple"
@change="uploadImg"
/>
</div>
</template>
<script>
import { defineComponent, getCurrentInstance } from "vue";
export default defineComponent({
name: "About",
setup() {
const { proxy } = getCurrentInstance();
function uploadImg() {
var fileInput = document.getElementById("fileInput");
var file = fileInput.files[0];
var blob = dataURLtoBlob(tobase64(file)); // 压缩图片
var aasfile = blobToFile(blob, file["name"]); // base64 转 Blob
var imgFile = new File([aasfile], file["name"], { // Blob 转File
type: "image/jpeg",
});
var formData = new FormData();
formData.append("imgFile", imgFile);
proxy.$axios.post("/avatar/upload", formData) // 网络请求
.then((result) => {
console.log(result);
}).catch(() => {
console.log("error");
});
}
/*
* 参数blob : Blob(File)实例对象,即二进制数据对象
* 图片压缩思路:
* 1.通过FileReader将Blob实例对象(二进制数据对象)转为一个url,赋给Image实例对象的src属性;
* 2.再通过Canvas的drawImage方法画图,最后再通过Canvas的toDataURL()方法进行Base64压缩,返回DataURL
*/
function tobase64(blob) {
var fileReader = new FileReader()
fileReader.readAsDataURL(blob)
fileReader.onload = () => { // onload : 文件读取完后事件
var img = new Image()
img.src = fileReader.result
img.onload = () => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d') // 平面图画笔
const width = img.width
const height = img.height
canvas.width = width // 画布宽 = 图片宽
canvas.height = height // 画布高 = 图片高
ctx.drawImage(img, 0, 0, width, height)
const dataURL = canvas.toDataURL('image/jpeg', 0.6) // 第二个参数:值越小,压缩后的图片越模糊
// console.log(dataURL)
// document.body.appendChild(canvas) // 显示画好的图片
return dataURL
}
}
}
//将base64转换为blob 参数dataUrl:压缩后的dataUrl
function dataURLtoBlob(dataUrl) {
var arr = dataUrl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
//将blob转换为file
function blobToFile(theBlob, fileName) {
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
}
return {
uploadImg,
};
},
});
</script>