FileReader就是html5为我们提供的读取文件的api。
它的作用就是把文本流按指定格式读取到缓存,以供js调用。
FileReader有五种方法:
1.abort()
该方法可以取消 FileReader 的读取操作,触发之后 readyState 为已完成
2.readAsArrayBuffer()
用于启动读取指定的 Blob 或 File 内容。
当读取操作完成时,readyState 变成 DONE
并触发 loadend 事件,同时 result 属性中将包含一个 ArrayBuffer 对象以表示所读取文件的数据。
3.readAsBinaryString() 非正式环境使用
读取指定的 Blob 或 File 对象,当读取完成的时候,readyState 会变成DONE
并触发 loadend 事件,同时 result 属性将包含所读取文件原始二进制格式。
4.readAsDataURL()
读取指定的 Blob 或 File 对象。
读取操作完成的时候,readyState 会变成已完成
并触发 loadend 事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。
5.readAsText()
将 Blob 或者 File 对象转根据特殊的编码格式转化为内容(字符串形式)
这个方法是异步的,只有当执行完成后才能够查看到结果,如果直接查看是无结果的,并返回undefined
必须要挂载 实例下的 onload 或 onloadend 的方法处理转化后的结果
当转化完成后, readyState 这个参数就会转换 为 done 即完成态,
event("loadend") 挂载的事件会被触发,并可以通过事件返回的形参得到中的 FileReader.result 属性得到转化后的结果
DataURL固定格式:
data:[文件格式];base64,[文本流base64编码]。
检测浏览器对FileReader的支持
if (window.FileReader) {
console.log('support')
var fileReader = new FileReader()
} else {
console.log('not support')
}
根据input框获取File对象,通过FileReader对File对象进行处理:
选文件input标签: <input type="file" ref="chooseFile" @change="onChange" value="choose"/>
file对象: this.$refs['chooseFile'].files[0]
FileReader对File对象读取成DataUrl格式数据: fileReader.readDataURL(this.$refs['chooseFile'].files[0])
通过readAsDataUrl读取文件后,获取DataUrl数据: fileReader.onload = function() { let dataUrl = fileReader.result }
fileReader.reuslt数据可以直接放入img.src中作为图片本地路径预览图片
如果需要对图片进行压缩,可以对fileReader.result指向的dataUrl数据进行压缩处理
最后将压缩的dataUrl数据转换为blob格式数据进行上传
图片压缩demo
<template>
<div>
<input type="file" ref="chooseFile" @change="onChange" value="choose"/>
<img :src="imgSrc" style="width:100px;height:100px;border:1px solid red;" ref="imgs"/>
</div>
</template>
<script>
export default {
data () {
return {
imgSrc: '',
// 用户id
userId: '',
// 上传url
actionUrl: ''
}
},
methods: {
onChange (event) {
if (window.FileReader) {
console.log('support FileReader')
console.log('event', event)
console.log('file', this.$refs['chooseFile'].files[0])
let file = this.$refs['chooseFile'].files[0]
let imgs = this.$refs['imgs']
let fileReader = new FileReader()
let localThis = this
fileReader.readAsDataURL(file)
fileReader.onload = function () {
let img = new Image()
img.src = fileReader.result
console.log(fileReader.result.length)
console.log('img', img)
img.onload = function () {
// 图片压缩
let data = localThis.compress(img)
// dataUrl转bolb数据
let bolb = localThis.dataURItoBlob(data)
}
}
console.log('content', content)
} else {
console.log('do not support FileReader')
}
},
// 图片压缩
compress (img) {
let canvas = document.createElement("canvas")
let ctx = canvas.getContext("2d")
let initSize = img.src.length
let width = img.width
let height = img.height
canvas.width = width
canvas.height = height
// 铺底色 这个步骤是必须的,只有将imgage绘制在canvas才能压缩
ctx.fillStyle = "#fff"
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(img, 0, 0, width, height)
//进行最小压缩
let ndata = canvas.toDataURL("image/jpeg", 0.1);
// console.log("*******压缩后的图片大小*******");
// console.log(ndata)
console.log(ndata.length);
return ndata;
},
// dataUrl 转 blob
dataURItoBlob (base64Data) {
var byteString;
if (base64Data.split(",")[0].indexOf("base64") >= 0) {
byteString = atob(base64Data.split(",")[1])
} else {
byteString = unescape(base64Data.split(",")[1])
}
var mimeString = base64Data
.split(",")[0]
.split(":")[1]
.split(";")[0]
var ia = new Uint8Array(byteString.length)
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i)
}
return new Blob([ia], { type: mimeString })
},
// dataUrl 抓 blob第二种写法
dataURItoBlob2 () {
let arr = dataURI.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], {type: mime})
},
// 图片上传
uploadPic (blob, fileName) {
let config = {
headers: {'Content-Type': 'multipart/form-data'}
}
let formData = new FormData()
formData.append('file', blob, fileName)
formData.append('userId', this.userId)
axios.post(this.actionUrl, formData, config)
.then((res) => {
if (res.flag === 'true') { console.log('上传成功!') }
})
.catch((error) => { console.log('错误:' + error )})
}
}
}
</script>
<style lang="less" scoped>
</style>