vue中使用canvas压缩图片上传
直接上代码,以备后查或者ctrl+c ,嘿嘿
有疑问可留言
压缩原理
- 使用canvas压缩图片,涉及到一些对象的转换,比如file对象转换成dataUrl
- blob 对象转换成file对象
- 使用axios实现上传
其中的一些方法复制即用,无需修改
全部代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>阿凡提汽配汽修平台</title>
<link rel="stylesheet" href="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/css/vant.css">
<link rel="stylesheet" href="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/css/common.css">
<link rel="stylesheet" href="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/css/publishpage.css">
<script src="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/js/vue.min.js"></script>
<script src="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/js/vant.min.js"></script>
<script src="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/js/axios.min.js"></script>
<!-- <script src="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/js/common.js?v=2"></script> -->
<style>
.van-index-anchor {
background-color: #ccc;
padding: 0 3vw !important;
height: 5vw !important;
line-height: 5vw !important;
font-size: 3vw !important;
}
img{
width:100%;
}
.container {
width: 0;
height: 0;
overflow: hidden;
}
canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<div class="container">
<canvas width="0" height="0"></canvas>
</div>
<div id="app">
<div class="publish-page">
<div class="nav">
<image class="nav-img"
src="http://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/icon/icon/ico_zuo.png"></img>
<div class="nav-title">发布信息</div>
</div>
<div class="nav-null-box"></div>
<p>测试</p>
<van-uploader v-model="fileList" multiple max-count="3"></van-uploader>
<van-button @click="toSubmit">上传</van-button>
<img :src="myImg" alt="hehe">
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
fileList: [],
myImg: '',
imgNum: null,
},
methods: {
// 上传图片
toSubmit() {
this.toCanvas()
},
toCanvas() {
var _this = this
this.imgNum = this.fileList.length
if (this.fileList && this.fileList.length > 0) {
for (var i = 0; i < this.fileList.length; i++) {
console.log(this.fileList[i].file)
var imgName = this.fileList[i].file.name
var imgType = this.fileList[i].file.type
this.readFileAsDataURL(this.fileList[i].file, function (imgurl) {
_this.myImg = imgurl
var image = new Image()
image.src = imgurl
image.onload = function () {
var myCanvas = document.querySelector('canvas')
var ctx = myCanvas.getContext('2d')
var imageWidth = image.width
var imageHeight = image.height
//定义压缩后的宽度,也可封装后调用时传入
var img_width = 750 //此处的750是压缩后图片的宽度,也是canvas画布的宽度
//宽度750 ,通过计算可得出缩放后的高
myCanvas.height = img_width * imageHeight / imageWidth
myCanvas.width = img_width
ctx.drawImage(image, 0, 0, imageWidth, imageHeight, 0, 0, img_width, img_width * imageHeight / imageWidth)
var bloburl = myCanvas.toDataURL(imgType);
var blob = _this.dataURLtoBlob(bloburl);
// let files = ([this.blob], file.name, {type: file.type})
// blob = _this.blobToFile(blob ,imgName)
var file = _this.blobToFile(blob, imgName)
let files = new window.File([blob], imgName, { type: imgType })
console.log(files)
_this.uploadfile(file, 0, '测试', function (im) { //括号中是一些测试的数据
_this.tips = '第' + im + "张图片上传成功"
}, i)
}
})
}
} else {
this.step = 6;
this.num = 3;
this.modelShow = false
}
},
readFileAsDataURL(file, callback) {
var a = new FileReader();
a.readAsDataURL(file);
a.onload = function (e) { callback(e.target.result); };
},
//将base64转换为blob
dataURLtoBlob: function (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
blobToFile: function (theBlob, fileName) {
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
},
uploadfile(file, id, name, callback, i) {
var _this = this
let fd = new FormData();
fd.append("file", file);
fd.append("name", name);
fd.append("type_id", id);
axios.post("https://www.xxx.com/xxx/xxx", fd, { //https://www.xxx.com/xxx/xxx对应自己的接口
headers: {
"Content-Type": "multipart/form-data",
charset: "UTF-8"
},
transformRequest: [
function () {
return fd;
}
]
}).then(function () {
callback(i)
_this.imgNum--
if (_this.imgNum <= 0) {
_this.step = 6;
_this.num = 3;
_this.modelShow = false
}
})
},
},
created() {
}
})
</script>
</body>
</html>