【前端Canvas】Vue+Vant Uploader 实现图片文件压缩上传

vant官网时常连接超时:vant源码

需求

base64传输图片。
限量图片数9。
上传图片超过1 * 1024 * 1024 byte就压缩。

结果

3M的图片压缩到70KB,上传输效率提高了十倍。

代码

					<!--需求:base64传输图片。限量图片数9。上传图片超过1*1024*1024 byte就压缩。-->
					<van-uploader v-model="tempFiles" multiple accept="image/*,video/*" :after-read="afterReaderFiles" :max-count="9">
					</van-uploader>
					<!--查看压缩之后的图片:还原组件回显图片样式,预览-->
					<div>
						<img :src="item" v-for="(item,index) in pressImgUrl" :key="index"
						     @click="ImagePreview(item)"
						     alt="压缩之后的图片" width="80px" height="80px"
						     style="object-fit: cover;border-radius: 8px;margin-right:8px">
					</div>
					

methods部分代码,主要是对 file 的base64 进行处理,file的数据内容:文档流File,base64。

			/**
			 * 文件流读取完成
			 * @param file
			 */
			async afterReaderFiles(file) {
				console.log(file);
				/*let regExp = /^video\//;*/
				if (file instanceof Array) {			// 多文件 Array
					file.forEach(fileItem => {
						console.log(fileItem);
						debugger;
						this.afterReaderFiles(fileItem);
					});
				} else {			// 单 Object
/*					if (regExp.test(file.file.type)) {
						this.videoOpretion(file);
						return
					};*/
					if (file.file.size > 1024 * 1024) {
						this.pressImgUrl.push(await this.imageCompress(file.content));
					}
				}
			},
			/**
			 * 图片压缩 base64->canvas->base64
			 * @param base64
			 */
			imageCompress(base64) {
				let Img = new Image(), dataURL = '';
				Img.src = base64;
				let p = new Promise(function (resolve, reject) {
					Img.onload = function () { //要先确保图片完整获取到,这是个异步事件
						let canvas = document.createElement("canvas"), //创建canvas元素
							width = Img.width, //确保canvas的尺寸和图片一样
							height = Img.height;
						// 默认将长宽设置为图片的原始长宽,这样在长宽不超过最大长度时就不需要再处理
						let ratio = width / height,
							maxLength = 1000,
							newHeight = height,
							newWidth = width;
						// 在长宽超过最大长度时,按图片长宽比例等比缩小
						if (width > maxLength || height > maxLength) {
							if (width > height) {
								newWidth = maxLength;
								newHeight = maxLength / ratio;
							} else {
								newWidth = maxLength * ratio;
								newHeight = maxLength;
							}
						};
						canvas.width = newWidth;
						canvas.height = newHeight;
						canvas.getContext("2d").drawImage(Img, 0, 0, newWidth, newHeight); //将图片绘制到canvas中
						dataURL = canvas.toDataURL('image/jpeg', 0.5); //转换图片为dataURL
						resolve(dataURL);
					};
				});
				return p
			},

总结

  • 其实需求还有video传输,一期迭代此功能已完成,但还需再后期迭代中做进一步完善。
  • 思路:使用JSZIP 插件对video压缩,采用multipart/form-data形式上传文档流数据。

这是前端最常见的File上传压缩上传方式,如果File超huge,可以使用Blob.slice方法对File文件进行分块提高性能。

  • 需求还有重复图片筛选上传。

  • 思路:根据file.file.name进行筛选。如果要严格根据图片内容相似度筛选,可用 base64数据进行判断。如果base64数据内容太长,可用MD5(base64)等算法处理之后进行判断。

  • 移动端浏览器兼容,以及机型兼容目前发现e+7以下的手机存在兼容问题。

评论 2 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

素心2020

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值