视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
2020-11-27 21:55:21 责编:小采
文档


面向百度开发

html

 <van-uploader :after-read="onRead" accept="image/*">
 <img src="./icon_input_add.png" />
 </van-uploader>

js

data() {
 return {
 files: {
 name: "",
 type: ""
 },
 headerImage: null,
 picValue: null,
 upImgUrl,
 }
 },
 // 组件方法 获取 流
 async onRead(file) {
 // console.log(file);
 // console.log(file.file);
 this.files.name = file.file.name; // 获取文件名
 this.files.type = file.file.type; // 获取类型
 this.picValue = file.file; // 文件流
 this.imgPreview(this.picValue);
 },
 // 处理图片
 imgPreview(file) {
 let self = this;
 let Orientation;
 //去获取拍照时的信息,解决拍出来的照片旋转问题
 Exif.getData(file, function () {
 Orientation = Exif.getTag(this, "Orientation");
 });
 // 看支持不支持FileReader
 if (!file || !window.FileReader) return;
 if (/^image/.test(file.type)) {
 // 创建一个reader
 let reader = new FileReader();
 // 将图片2将转成 base 格式
 reader.readAsDataURL(file);
 // 读取成功后的回调
 reader.onloadend = function () {
 // console.log(this.result);
 let result = this.result;
 let img = new Image();
 img.src = result;
 //判断图片是否大于500K,是就直接上传,反之压缩图片
 if (this.result.length <= 500 * 1024) {
 self.headerImage = this.result;
 self.postImg();
 } else {
 img.onload = function () {
 let data = self.compress(img, Orientation);
 self.headerImage = data;
 self.postImg();
 };
 }
 };
 }
 },
 // 压缩图片
 compress(img, Orientation) {
 let canvas = document.createElement("canvas");
 let ctx = canvas.getContext("2d");
 //瓦片canvas
 let tCanvas = document.createElement("canvas");
 let tctx = tCanvas.getContext("2d");
 // let initSize = img.src.length;
 let width = img.width;
 let height = img.height;
 //如果图片大于四百万像素,计算压缩比并将大小压至400万以下
 let ratio;
 if ((ratio = (width * height) / 4000000) > 1) {
 // console.log("大于400万像素");
 ratio = Math.sqrt(ratio);
 width /= ratio;
 height /= ratio;
 } else {
 ratio = 1;
 }
 canvas.width = width;
 canvas.height = height;
 // 铺底色
 ctx.fillStyle = "#fff";
 ctx.fillRect(0, 0, canvas.width, canvas.height);
 //如果图片像素大于100万则使用瓦片绘制
 let count;
 if ((count = (width * height) / 1000000) > 1) {
 // console.log("超过100W像素");
 count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
 // 计算每块瓦片的宽和高
 let nw = ~~(width / count);
 let nh = ~~(height / count);
 tCanvas.width = nw;
 tCanvas.height = nh;
 for (let i = 0; i < count; i++) {
 for (let j = 0; j < count; j++) {
 tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
 ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
 }
 }
 } else {
 ctx.drawImage(img, 0, 0, width, height);
 }
 //修复ios上传图片的时候 被旋转的问题
 if (Orientation != "" && Orientation != 1) {
 switch (Orientation) {
 case 6: //需要顺时针(向左)90度旋转
 this.rotateImg(img, "left", canvas);
 break;
 case 8: //需要逆时针(向右)90度旋转
 this.rotateImg(img, "right", canvas);
 break;
 case 3: //需要180度旋转
 this.rotateImg(img, "right", canvas); //转两次
 this.rotateImg(img, "right", canvas);
 break;
 }
 }
 //进行最小压缩
 let ndata = canvas.toDataURL("image/jpeg", 0.1);
 tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
 return ndata;
 },
 // 旋转图片
 rotateImg(img, direction, canvas) {
 //最小与最大旋转方向,图片旋转4次后回到原方向
 const min_step = 0;
 const max_step = 3;
 if (img == null) return;
 //img的高度和宽度不能在img元素隐藏后获取,否则会出错
 let height = img.height;
 let width = img.width;
 let step = 2;
 if (step == null) {
 step = min_step;
 }
 if (direction == "right") {
 step++;
 //旋转到原位置,即超过最大值
 step > max_step && (step = min_step);
 } else {
 step--;
 step < min_step && (step = max_step);
 }
 //旋转角度以弧度值为参数
 let degree = (step * 90 * Math.PI) / 180;
 let ctx = canvas.getContext("2d");
 switch (step) {
 case 0:
 canvas.width = width;
 canvas.height = height;
 ctx.drawImage(img, 0, 0);
 break;
 case 1:
 canvas.width = height;
 canvas.height = width;
 ctx.rotate(degree);
 ctx.drawImage(img, 0, -height);
 break;
 case 2:
 canvas.width = width;
 canvas.height = height;
 ctx.rotate(degree);
 ctx.drawImage(img, -width, -height);
 break;
 case 3:
 canvas.width = height;
 canvas.height = width;
 ctx.rotate(degree);
 ctx.drawImage(img, -width, 0);
 break;
 }
 },
 //将base转换为文件
 dataURLtoFile(dataurl) {
 var arr = dataurl.split(","),
 bstr = atob(arr[1]),
 n = bstr.length,
 u8arr = new Uint8Array(n);
 while (n--) {
 u8arr[n] = bstr.charCodeAt(n);
 }
 return new File([u8arr], this.files.name, {
 type: this.files.type
 });
 },
 //这里写接口 
 async postImg() {
 let file = this.dataURLtoFile(this.headerImage);
 let formData = new window.FormData();
 formData.append("file", file);
 toast_loding(this, "图片上传中···");
 try {
 let res = await util.ajax.post(this.upImgUrl, formData, {
 headers: {
 "Content-Type": "multipart/form-data"
 }
 });
 } catch (e) {
 console.log(e);
 }
 }

总结

以上所述是小编给大家介绍的移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢! 

下载本文
显示全文
专题