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

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

需求

base64传输图片。
限量图片数9。
上传图片超过1 * 1024 * 1024 byte就压缩。
【前端Canvas】Vue+Vant Uploader 实现图片文件压缩上传_第1张图片

结果

3M的图片压缩到70KB,上传输效率提高了十倍。
【前端Canvas】Vue+Vant Uploader 实现图片文件压缩上传_第2张图片

代码

					<!--需求: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。
【前端Canvas】Vue+Vant Uploader 实现图片文件压缩上传_第3张图片

			/**
			 * 文件流读取完成
			 * @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以下的手机存在兼容问题。

你可能感兴趣的:(vue.js,javascript)