前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue.js + axios.js图片压缩处理并上传到服务器demo

vue.js + axios.js图片压缩处理并上传到服务器demo

作者头像
别盯着我的名字看
发布2022-06-09 11:22:18
5.5K0
发布2022-06-09 11:22:18
举报
文章被收录于专栏:前端专栏前端专栏

点击查看效果

图片压缩原理

将图片重新画入一个canvas中。可设置最大宽度,再按图片宽高比例定义canvas画布的宽高。

完整代码demo

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传图片</title>
    <meta name="renderer" content="webkit">
    <meta name="viewport"
          content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>

    <link rel="stylesheet" href="css/upload-img.css">
</head>
<body>
<div id="app" class="container" v-cloak>
    <div class="uploading-data" v-if="isUploading"></div>

    <div class="upload-img-column">
        <div class="words">上传图片 ({{imgTempList.length}}/5)</div>
        <div class="upload-wrap">
            <div class="box">
                <label class="p dotted">
                    <input type="file" accept="image/jpg,image/jpeg,image/png" name="file"
                           @change="onChooseImage($event)"/>
                    <img src="./img/jiahao.png" alt="">
                </label>
            </div>
            <template v-for="(imgItem, imgIndex) in imgTempList">
                <div class="box">
                    <div class="p">
                        <img :src="imgItem">
                        <div class="delete" @click.stop="deleteImg(imgIndex)">
                            <img src="./img/guanbi.png" alt="">
                        </div>
                    </div>
                </div>
            </template>
        </div>
    </div>

    <button class="l-btn" @click="onUploadImg">上传</button>

    <!-- 图片上传成功后返回的路径(没必要的) -->
    <div class="success-path">
        <template v-for="(item, index) in successPath">
            <a :href="item" target="_blank">{{item}}</a>
        </template>
    </div>

</div>

<script src="js/vue-2.5.21.js"></script>
<script src="js/axios.js"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            imgTempList: [], //图片临时路径列表
            isUploading: false, //是否正在上传
            successPath: [], //上传成功后的路径(没必要)
        },
        mounted: function () {
            var that = this;
        },
        watch: {},
        methods: {
            //选择图片
            onChooseImage: function (event) {
                var that = this;

                //判断图片数量是否已上限
                var currentImgTempArray = that.imgTempList;
                if (currentImgTempArray.length >= 5) {
                    alert("最多上传5张图片");
                    return false;
                }

                //使用FileReader对文件对象进行操作
                var reader = new FileReader();
                reader.readAsDataURL(event.target.files[0]); //将读取到的文件编码成Data URL
                reader.onload = function () { //读取完成时
                    var replaceSrc = reader.result; //文件输出的内容


                    //调用图片压缩处理方法
                    that.compressedImage({
                        src: replaceSrc,
                        quality: 0.8,
                        success: function (src) {
                            //将压缩后的路径 追加到临时路径数组中
                            var totalList = [];
                            if (currentImgTempArray.length > 0) {
                                totalList = currentImgTempArray.concat(src);
                            } else {
                                totalList[0] = src;
                            }
                            that.imgTempList = totalList;
                        }
                    });
                };

            },

            //删除某张图片
            deleteImg: function (idx) {
                var that = this;
                that.imgTempList.splice(idx, 1);
            },


            //提交上传图片
            onUploadImg: function () {
                var that = this;
                var imgTempList = that.imgTempList;
                if (imgTempList.length > 0) {

                    that.isUploading = true; //正在上传 显示遮罩层 防止连续点击

                    var countNum = 0; //计算数量用的 判断上传到第几张图片了

                    //map循环遍历上传图片
                    imgTempList.map(function (imgItem, imgIndex) {
                        var files = that.dataURLtoFile(imgItem, 'pj' + Date.now() + '.jpg'); //DataURL转File

                        //创FormData对象
                        var formdata = new FormData();
                        //append(key,value)在数据末尾追加数据。 这儿的key值需要和后台定义保持一致
                        formdata.append('img', files);

                        //用axios上传,
                        axios({
                            method: "POST",
                            url: "http://www.clluo.com:8060/uploadImg",
                            data: formdata,
                            headers: {
                                "Content-Type": "multipart/form-data"
                            }
                        }).then(function (res) {
                            countNum++;
                            //图片全部上传完后去掉遮罩层
                            if (countNum >= imgTempList.length) {
                                that.isUploading = false;
                            }

                            //没必要的代码 👇
                            var list = [];
                            if (that.successPath.length > 0) {
                                list = that.successPath.concat(res.data.path);
                            } else {
                                list[0] = res.data.path;
                            }
                            that.successPath = list;

                        }).catch(function (error) {
                            console.error(error);
                        });
                    });
                }
            },

            /**
             * 压缩图片处理
             * @src 需要压缩的图片base64路径
             * @quality 图片质量 0-1,默认1
             * @success()  成功后的回调
             * */
            compressedImage: function (params) {
                var that = this;

                var initParams = {
                    src: params.src || "",
                    quality: params.quality || 1,
                };

                var image = new Image();
                image.src = initParams.src;
                image.onload = function () {
                    //获取图片初始宽高
                    var width = image.width;
                    var height = image.height;
                    //判断图片宽度,再按比例设置宽度和高度的值
                    if (width > 1024) {
                        width = 1024;
                        height = Math.ceil(1024 * (image.height / image.width));
                    }

                    //将图片重新画入canvas中
                    var canvas = document.getElementById("compressCanvas");
                    if(!canvas){ //创建一个canvas画布
                        var body = document.body;
                        canvas = document.createElement("canvas"); //创建canvas标签
                        canvas.id = "compressCanvas"; //给外层容器添加一个id
                        canvas.style.position = "fixed";
                        canvas.style.zIndex = "-1";
                        canvas.style.opacity = "0";
                        canvas.style.top = "-100%";
                        canvas.style.left = "-100%";
                        body.append(canvas);
                    }

                    var context = canvas.getContext("2d");
                    canvas.width = width;
                    canvas.height = height;
                    context.beginPath();
                    context.fillStyle = "#ffffff";
                    context.fillRect(0, 0, width, height);
                    context.fill();
                    context.closePath();
                    context.drawImage(image, 0, 0, width, height);
                    var replaceSrc = canvas.toDataURL("image/jpeg", initParams.quality); //canvas转DataURL(base64格式)

                    params.success && params.success(replaceSrc);
                };
            },

            /**
             * 将base64转换为文件
             * @dataUrl base64路径地址
             * @fileName 自定义文件名字
             * */
            dataURLtoFile: function (dataUrl, fileName) {
                var arr = dataUrl.split(','), mime = arr[0].match(/:(.*?);/)[1],
                    bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
                while (n--) {
                    u8arr[n] = bstr.charCodeAt(n);
                }
                return new File([u8arr], fileName, {type: mime});
            },
        }
    });
</script>
</body>
</html>

css代码

代码语言:javascript
复制
[v-cloak] {
	display: none;
}

* {
	margin: 0;
	padding: 0;
	list-style: none;
	box-sizing: border-box;
	-moz-box-sizing: border-box;
	-webkit-box-sizing: border-box;
	word-break: break-all;
	word-wrap: break-word;
}

.container {
	width: 100%;
	max-width: 600px;
	min-width: 320px;
	margin: 0 auto;
}

.container .l-btn {
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	width: 150px;
	height: 40px;
	color: #fff;
	background: #05AFAE;
	border: none;
	border-radius: 5px;
	-webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, .1);
	        box-shadow: 1px 2px 3px rgba(0, 0, 0, .1);
	margin: 50px auto;
	-webkit-box-orient: horizontal;
	-webkit-box-direction: normal;
	    -ms-flex-direction: row;
	        flex-direction: row;
	-webkit-box-align: center;
	    -ms-flex-align: center;
	        align-items: center;
	-webkit-box-pack: center;
	    -ms-flex-pack: center;
	        justify-content: center;
}

.container .l-btn:focus {
	outline: none;
}

.container .l-btn:active {
	-webkit-transition: .1s;
	-o-transition: .1s;
	transition: .1s;
	-webkit-transform: scale(.95);
	    -ms-transform: scale(.95);
	        transform: scale(.95);
}


/* 上传图片栏目 START */
.upload-img-column {
	width: 100%;
	padding: 10px;
}

.upload-img-column .words {
	font-size: 14px;
}

.upload-img-column .upload-wrap {
	width: 100%;
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-orient: horizontal;
	-webkit-box-direction: normal;
	    -ms-flex-direction: row;
	        flex-direction: row;
	-ms-flex-wrap: wrap;
	    flex-wrap: wrap;
}

.upload-img-column .upload-wrap .box {
	width: 33.33%;
	padding: 10px 10px 0 0;
}

.upload-img-column .upload-wrap .box .p {
	width: 100%;
	height: 0;
	padding-bottom: 100%;
	border-radius: 5px;
	position: relative;
	overflow: hidden;
}

.upload-img-column .upload-wrap .box .p img {
	position: absolute;
	width: 100%;
	height: 100%;
	border-radius: 5px;
	overflow: hidden;
	left: 50%;
	top: 50%;
	-webkit-transform: translate(-50%, -50%);
	    -ms-transform: translate(-50%, -50%);
	        transform: translate(-50%, -50%);
}

.upload-img-column .upload-wrap .box .p .delete {
	width: 30px;
	height: 30px;
	text-align: center;
	border-radius: 50%;
	background: #e0e0e0;
	position: absolute;
	right: 0;
	top: 0;
	z-index: 2;
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-orient: horizontal;
	-webkit-box-direction: normal;
	    -ms-flex-direction: row;
	        flex-direction: row;
	-webkit-box-align: center;
	    -ms-flex-align: center;
	        align-items: center;
	-webkit-box-pack: center;
	    -ms-flex-pack: center;
	        justify-content: center;
	opacity: 0.8;
}

.upload-img-column .upload-wrap .box .p .delete:active {
	-webkit-transform: scale(0.95);
	    -ms-transform: scale(0.95);
	        transform: scale(0.95);
}

.upload-img-column .upload-wrap .box .p .delete img {
	width: 14px;
	height: 14px;
}

.upload-img-column .upload-wrap .box .p.dotted {
	display: block;
	border: dotted 2px #999;
}

.upload-img-column .upload-wrap .box .p.dotted input {
	display: none;
}

.upload-img-column .upload-wrap .box .p.dotted img {
	width: 60%;
	height: auto;
	position: absolute;
	left: 50%;
	top: 50%;
	-webkit-transform: translate(-50%, -50%);
	    -ms-transform: translate(-50%, -50%);
	        transform: translate(-50%, -50%);
	opacity: .8;
}

/* 上传图片栏目 END */

.uploading-data {
	position: fixed;
	width: 100%;
	height: 100%;
	background: rgba(255, 255, 255, 0.3);
	left: 0;
	top: 0;
	z-index: 1000;
}

.success-path {
	width: 100%;
	padding: 0 10px;
}

.success-path a {
	display: block;
	margin-top: 6px;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-5-7,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 图片压缩原理
  • 完整代码demo
  • css代码
相关产品与服务
图片处理
图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档