vue 利用canvas做图片压缩上传

2018-09-26  本文已影响0人  zx一个胖子

文中的注释 有助于更好的理解

HTML

<input @change="fileChange($event)" type="file" accept="image/*" > //上传图片类型
<div class="add">
                <input @change="fileChange($event)" type="file" accept="image/*" >
                <div class="add-image">
                    <div class="add-ico">
                        <img src="../../../static/info3.png" alt="">
                    </div>
                    <img class="add-img" v-show="imgL" :src="imgL" alt="">
                </div>
                <p class="font13">点击上传名片</p>
</div>

Methods

//判断是否图片类型
fileChange(el) {
           // console.log(el.target.files[0].size)
            if (!el.target.files[0].size){
                this.$msgbox("请选择图片文件")
                return
            }else{
                this.fileList(el.target);
                el.target.value = ''
            }
            
        },

//判断是否为文件夹文件
fileList(fileList) {
              let files = fileList.files;
                //判断是否为文件夹
                if (files.type != '') {
                    this.fileAdd(files);
                } else {
                    this.$msgbox("请选择图片文件")
                }
        },

fileAdd(file) {
            //判断是否为图片文件
            if (file.type.indexOf('image') == -1) {
                this.$msgbox("请选择图片文件")
            } else {
                let reader = new FileReader();
                let image = new Image();
                let _this = this;
                reader.readAsDataURL(file);
                reader.onload = function () {
                    file.src = this.result;
                    image.onload = function(){
                        let width = image.width;
                        let height = image.height;
                        file.width = width;
                        file.height = height;
                        _this.imgL = file.src  //页面上显示所选择的图片
                    };
                    console.log(file)
                    image.src= file.src; //页面上显示所选择的图片
                    if(file.size/1024 > 1025){  //判断图片的大小,超过1M 进行压缩
                        _this.imgCompress(file,{quality: 0.2})
                    }else{
                        _this.partitionBase = file.src.split(",")[1]  //这里是因为后台需要 base64和图片type类型两个数据,所以进行了处理
                        _this.imgType ="."+file.type.split("/")[1]
                    }
                }
            }
        },

//图片压缩
        imgCompress(path,obj){   //path是指上传的图片,obj是压缩的品质,越低越模糊
            let _this = this  //这里的this 是把vue的实例对象指向改变为_this 
            var img = new Image();
            img.src = path.src;
            img.onload = function(){
                var that = this;  //这里的this 是把img的对象指向改变为that 
                // 默认按比例压缩
                var w = that.width,
                    h = that.height,
                    scale = w / h;
                w = obj.width || w;
                h = obj.height || (w / scale);
                var quality = 0.7;  // 默认图片质量为0.7
                //生成canvas
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                // 创建属性节点
                var anw = document.createAttribute("width");
                anw.nodeValue = w;
                var anh = document.createAttribute("height");
                anh.nodeValue = h;
                canvas.setAttributeNode(anw);
                canvas.setAttributeNode(anh);
                ctx.drawImage(that, 0, 0, w, h);
                // 图像质量
                if(obj.quality && obj.quality <= 1 && obj.quality > 0){
                    quality = obj.quality;
                }
                // quality值越小,所绘制出的图像越模糊
                var base64 = canvas.toDataURL('image/jpeg', quality);
                // 回调函数返回base64的值
                var urlFile = _this.convertBase64UrlToBlob(base64)  //这个地方的处理是为了把压缩的base64转化为对象,获得压缩后图片的大小size,方便对压缩后的图片再次进行判断;
                console.log(urlFile)
                if(urlFile.size/1024 > 1025){
                    _this.$msgbox("图片过大,请重新上传图片")
                }else{
                    _this.partitionBase = base64.split(",")[1]
                    _this.imgType ="."+urlFile.type.split("/")[1]
                }
            }
        },

//将base64码转化为file(Blob)
        //此处函数对压缩后的base64经过处理返回{size: "", type: ""} 
        convertBase64UrlToBlob(urlData){
            var arr = urlData.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 Blob([u8arr], {type:mime});
        },

至此,图片就压缩完成了
经测试,2M的图片,压缩后的大小为20多K。(图片没什么花里胡哨的东西)

上一篇下一篇

猜你喜欢

热点阅读