vant上传图片进行图片压缩

1、在config/utils文件封装通用的图片压缩方法

// 图片压缩
export const imgPreview = (file, callback) => {
    //将base64转换为文件
    function dataURLtoFile(dataurl, file) {
        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], file.name, {
            type: file.type
        });
    }
    // 压缩图片
    function compress(img) {
        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);
        }
        //进行最小压缩
        let ndata = canvas.toDataURL("image/jpeg", 0.3);
        tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
        return ndata;
    }
    // 看支持不支持FileReader
    if (!file || !window.FileReader) {
        return;
    }
    if (/^image/.test(file.type)) {
        // 创建一个reader
        let reader = new FileReader();
        // 将图片转成 base64 格式
        reader.readAsDataURL(file);
        // 读取成功后的回调
        reader.onloadend = function() {
            let result = this.result;
            let img = new Image();
            img.src = result;
            //判断图片是否大于500K,是就直接上传,反之压缩图片
            if (this .result.length <= 100 * 1024) {
                // 上传图片
                let imageFile = dataURLtoFile(this.result, file);
                callback(imageFile);
            } else {
                img.onload = function() {
                    let data = compress(img);
                    // 上传图片
                    let imageFile = dataURLtoFile(data, file);
                    callback(imageFile);
                };
            }
        };
    }
};

2、用法

import { imgPreview } from "@/config/utils.js";
//afterRead方法是vant的van-uploader提供的文件加载后方法
afterRead(file, detail) {
      let that = this;
      let index = detail.index;
      //上传的图片可能分为单张上传和多张上传
      if (file instanceof Array) {
        for (let i = 0; i < file.length; i++) {
          (function (arg) {
            let formData = new FormData();
            imgPreview(file[arg].file, async (files) => {
              formData.append("file", files);
              formData.append("kind", "indexPic");
              await check.fileUpload2(formData).then((res) => {
                if (res) {
                  let data = {};
                  data.jdlj = res.data.data[0].absUrl;
                  data.xdlj = res.data.data[0].url;
                  data.mc = res.data.data[0].name;
                  data.url = that.globalAddress + res.data.data[0].url;
                  that.tempList[index + i] = data;
                }
              });
            });
          })(i);
        }
      } else {
        let formData = new FormData();
        imgPreview(file.file, (files) => {
          formData.append("file", files);
          formData.append("kind", "indexPic");
          check.fileUpload2(formData).then((res) => {
            if (res) {
              let data = {};
              data.jdlj = res.data.data[0].absUrl;
              data.xdlj = res.data.data[0].url;
              data.mc = res.data.data[0].name;
              data.url = that.globalAddress + res.data.data[0].url;
              that.tempList[index] = data;
            }
          });
        });
      }
    },

解释:上传的图片可能是单张可能是多张,所以需要根据file是数组还是对象来执行不同的流程,如果是数组中进行图片压缩完成后,再调接口,可能会出现for循环中的异步操作这个经典问题,导致变量始终为最后一项,所以利用了闭包配合async/await来按顺序调取接口

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容