作者是在 vue 上做的开发, 可能对有学过 vue 学者比较友好
首先, 我们看看整个执行过程的类型转换
input --> FileList --> File --> base64 --> Blob --> ajax(Blob) 提交
那么先从元素开始吧
- html
- <input type="file" @change="upimg" accept="image/*" />
- JS
base64 转 blob
- // 此处转载 https://www.cnblogs.com/fj99/p/5502130.html
- /**
- *
- * @param {*base64 字符串} dataurl
- * @return {Blob 文件类型}
- */
- export 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});
- }
压缩图片代码 此处自创
- /**
- * 采用递归算法, 在移动端也测试过, 10M 也基本没问题, 现在的手机随便一张照片
- * 就上 3M 了, 这下可以减少不少服务器的负担
- *
- * @param {*img 标签的加载事件参数} img
- * @return {* 处理最终结果返回图片 base64 编码} base64data
- *
- */
- export function scaleimg(img){
- let height=img.currentTarget.height;
- let width=img.currentTarget.width;
- let base64data='';
- let can=document.createElement("canvas");
- can.height=height;
- can.width=width;
- let casimg=can.getContext('2d');
- casimg.clearRect(0, 0,width,height);
- casimg.drawImage(img.currentTarget,0,0,width,height);
- base64data=can.toDataURL('image/jpeg'); // 获取在 canvas 元素中的图片截图 base64 编码
- let size=Math.round( dataURLtoBlob(base64data).size/1024); // 获取压缩前的图片大小
- let maxsize=800; // 设置压缩后的最大值
- if(size>maxsize){
- if(size<1300){
- img.currentTarget.height=Math.round(height*(3/4));
- img.currentTarget.width=Math.round(width*(3/4));
- return scaleimg(img)
- }
- else if(size<1800){
- img.currentTarget.height=Math.round(height*(2/3));
- img.currentTarget.width=Math.round(width*(2/3));
- return scaleimg(img)
- }
- else{
- img.currentTarget.height=Math.round(height/2);
- img.currentTarget.width=Math.round(width/2);
- return scaleimg(img)
- }
- }
- else{
- console.log('压缩后大小'+size);
- return base64data;
- }
- }
change 事件方法
- import axios from "axios"
- import { dataURLtoBlob, scaleimg } from "./handlerimg.js";
- upimg(e) {
- let name = e.target.name
- let file = e.target.files[0]
- let filesize = file.size / 1024
- let data = new FileReader()
- let img = new Image()
- let formatdata = ""
- data.onload = e1 => {
- img.onload = e => {
- console.log("压缩前大小" + dataURLtoBlob(e1.target.result).size / 1024); // 压缩前大小
- if (/^image\/([a-zA-Z]|\*)+$/.test(file.type)) {
- formatdata = scaleimg(e)
- //#region 提交 Blob 格式图片文件
- let config = {
- headers: { "Content-Type": "multipart/form-data" }
- };
- let param = new FormData()
- param.append("file", dataURLtoBlob(formatdata));
- axios.post("/uploadimage", param, config).then(res => {
- this.$store.commit('showload',false) // 关闭加载动画
- document.getElementById('img').src=res.data
- }).catch(res=>{this.$store.commit('SET_showload',false)}) // 关闭加载动画
- //#endregion
- }
- };
- img.src = e1.target.result // 触发加载 img load 事件
- };
- this.$store.commit('showload',true) // 触发加载动画
- data.readAsDataURL(file) // 触发加载 filereader load 事件
- }
来源: https://www.jianshu.com/p/36f4f456d1c7