Vue用vant上传图片,前端上传之前压缩处理

27 篇文章 2 订阅
15 篇文章 2 订阅
  1. 提交时在上传服务器
  2. 同步上传服务器
  3. 上传之前压缩图片处理

一、提交时在上传服务器

<div class="uploader">
     <van-uploader  v-model="fileList"  accept="image/*" multiple  :max-count="countMax" />
 </div>
 <div @click="submit">提交</div>
<script>
    window.alert = function (name) {
        var iframe = document.createElement("IFRAME");
        iframe.style.display = "none";
        iframe.setAttribute("src", 'data:text/plain,');
        document.documentElement.appendChild(iframe);
        window.frames[0].window.alert(name);
        iframe.parentNode.removeChild(iframe);
    }
    new Vue({
        el: "#Vue",
        data: {
            countMax: 9,
            fileList: [],
            fileArr: []
        },
        created() {
            document.documentElement.style.fontSize = 16 * document.documentElement.clientWidth / 375 + 'px'
        },
        methods: {
            // 请求公共方法
            ajaximg(type, url, params, cb) {
                $.ajax({
                    type: type,
                    url: url,
                    data: params,
                    dataType: "json",
                    async: true,
                    contentType: false,
                    processData: false,
                    success: (response) => {
                        cb(response)
                    }
                });
            },
    //提交
            submit() {
                if (this.fileList.length < 2) {
                    vant.Toast("图片不能小于2张");
                    return false;
                }
                vant.Toast.loading({
                    message: "加载中...",
                    forbidClick: true,
                    duration: 0,
                });
                this.fileArr = [];
                this.getPreview(this.fileList, 0);
            },
            // 上传图片
            getPreview(file, i) {
                let fileUrl = file[i].file;
                let formData = new FormData();
                formData.append("file", fileUrl);
                formData.append("key", "Gn1xVdBiTClSSHKZifg0pTQSU5XGagWO");
                this.ajaximg('post','域名', formData, (res) => {
                    if (res.status == 200) {
                        this.fileArr.push(res.info.url);
                         if (i + 1 == this.fileList.length) {
                            this.setAdd();
                        }
                        if (++i < this.fileList.length) {
                            this.getPreview(file, i);
                        }
                    } else {
                        vant.Dialog.alert({
                            title: "温馨提示",
                            message: "图片上传失败,请重新上传",
                        }).then(() => { });
                    }
                })
            },
            setAdd() {
                console.log(this.fileArr)

                vant.Toast("上传成功");
            }
        }
    })
</script>

二、同步上传服务器

在这里插入图片描述

<van-uploader v-model="fileList" :after-read="afterRead" accept="image/*"
                        multiple :max-count="countMax" @delete='delImg' />
<van-button round block type="info" color="#FF7F50" @click="onSubmit">提交</van-button>

data() {
      return {
          fileList: [], //默认进来有的图片
          fileArr: [], //传给后台的图片
          countMax: 3,//最多上传3张
      };
  },

methods:{
	// 上传图片
	afterRead(file) {
	    if (!Array.isArray(file)) {
	        file = [file]
	    }
	    for (let i = 0; i < file.length; i++) {
	        let fileUrl = file[i].file;
	        file[i].status = 'uploading'
	        file[i].message = '上传中...'
	        let formData = new FormData();
	        formData.append("file", fileUrl);
	        formData.append("key", "Gn1xVdBiTClSSHKZifg0pTQSU5XGagWO");
	        axios({
	            method: 'post',
	            url: process.env.VUE_APP_SUCAI_API,
	            data: formData,
	        }).then((res) => {
	            if (res.data.status == 200) {
	                file[i].id = res.data.info.id
	                file[i].status = 'done'
	                file[i].message = '上传成功'
	                this.fileArr.push({
	                    url: res.data.info.url,
	                    id: res.data.info.id
	                });
	            } else {
	                file[i].status = 'failed'
	                file[i].message = '上传失败'
	                this.$toast.fail("有图片上传失败,请重新上传");
	            }
	        });
	    }
	},
	//删除图片
	delImg(e) {
	    let index = this.fileArr.map((item) => item.id).indexOf(e.id)
	    if (index != -1) {
	        this.fileArr.splice(index, 1)
	    }
	},
	// 提交
    onSubmit() {
         console.log('submit', this.fileArr);//提交给后台的数组
     },
}

三.上传之前压缩图片处理

在这里插入图片描述

先在utils新建一个imgPreview.js文件

// 图片压缩
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);
                };
            }
        };
    }
};

开始页面使用

 <van-uploader v-model="fileList" :after-read="afterRead" accept="image/*" multiple
                        :max-count="countMax" @delete='delImg' />
 import axios from "axios";
 import {
     imgPreview
 } from "../../utils/imgPreview.js";
 data() {
   return {
       fileList: [], //默认进来有的图片
       fileArr: [], //传给后台的图片
       countMax: 9,
   };
},
methods(){
 // 上传图片
 afterRead(file) {
     if (!Array.isArray(file)) {
         // 判断是否只有一张,则转为数组
         file = [file]
     }
     for (let i = 0; i < file.length; i++) {
         console.log('压缩之前图片大小', file[i].file.size)
         imgPreview(file[i].file, async (files) => {
             let fileUrl = files;
             file[i].status = 'uploading'
             file[i].message = '上传中...'
             let formData = new FormData();
             formData.append("file", fileUrl);
             formData.append("key", "Gn1xVdBiTClSSHKZifg0pTQSU5XGagWO");
             console.log('压缩之后图片大小', fileUrl.size)
             axios({
                 method: 'post',
                 url: process.env.VUE_APP_SUCAI_API,
                 data: formData,
             }).then((res) => {
                 if (res.data.status == 200) {
                     file[i].id = res.data.info.id
                     file[i].status = 'done'
                     file[i].message = '上传成功'
                     this.fileArr.push({
                         url: res.data.info.url,
                         id: res.data.info.id
                     });
                 } else {
                     file[i].status = 'failed'
                     file[i].message = '上传失败'
                     this.$toast.fail("有图片上传失败,请重新上传");
                 }
             });
         })
     }
 },
 //删除图片
 delImg(e) {
     let index = this.fileArr.map((item) => item.id).indexOf(e.id)
     if (index != -1) {
         this.fileArr.splice(index, 1)
     }
 },
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Vue前端开发中,可以使用Vant组件库中的Uploader组件来实现图片上传功能。同时,为了减小上传文件的大小,可以使用JavaScript中的canvas API对图片进行压缩处理。具体步骤如下: 1. 在Vue项目中引入Vant组件库和exif-js库。 2. 在Uploader组件中设置上传图片的最大尺寸和格式。 3. 在上传前,使用exif-js库获取图片的方向参数,并根据方向参数对图片进行旋转。 4. 使用canvas API对图片进行压缩处理,并将压缩后的图片上传至服务器。 代码示例: ``` <template> <van-uploader :max-size="2 * 1024 * 1024" :accept="['jpg', 'jpeg', 'png']" :before-upload="beforeUpload" :on-success="onSuccess" /> </template> <script> import EXIF from 'exif-js'; import { Toast } from 'vant'; export default { methods: { beforeUpload(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = (event) => { const img = new Image(); img.src = event.target.result; img.onload = () => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); let width = img.width; let height = img.height; let orientation = 1; EXIF.getData(file, function() { orientation = EXIF.getTag(this, 'Orientation'); }); if ([5, 6, 7, 8].indexOf(orientation) > -1) { canvas.width = height; canvas.height = width; } else { canvas.width = width; canvas.height = height; } switch (orientation) { case 2: ctx.transform(-1, 0, 0, 1, width, 0); break; case 3: ctx.transform(-1, 0, 0, -1, width, height); break; case 4: ctx.transform(1, 0, 0, -1, 0, height); break; case 5: ctx.transform(0, 1, 1, 0, 0, 0); break; case 6: ctx.transform(0, 1, -1, 0, height, 0); break; case 7: ctx.transform(0, -1, -1, 0, height, width); break; case 8: ctx.transform(0, -1, 1, 0, 0, width); break; default: break; } ctx.drawImage(img, 0, 0, width, height); const base64 = canvas.toDataURL('image/jpeg', 0.8); const blob = this.dataURLtoBlob(base64); resolve(blob); }; }; }); }, onSuccess(response) { Toast.success('上传成功'); }, dataURLtoBlob(dataURL) { const arr = dataURL.split(','); const mime = arr[0].match(/:(.*?);/)[1]; const bstr = atob(arr[1]); let n = bstr.length; const u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); }, }, }; </script> ```

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HqL丶1024

创作不易,谢谢打赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值