软件工程——头像压缩(g)

使用elementui组件el-upload 基于canvas进行图片压缩

参考网页:https://segmentfault.com/a/1190000012608763

主要解释了将file文件转为dataUrl,进行压缩再生成 blob对象 再生成formData对象 上传到服务器

主要代码:

      

1、修改el-upload的action=“dxx”(随便写)

2、需要放到userinfo/index里的methods里

            compress(img) {
                let canvas = document.createElement("canvas");
                let ctx = canvas.getContext("2d");
                let initSize = img.src.length;
                let width = img.width;
                let height = img.height;
                canvas.width = width;
                canvas.height = height;
                ctx.fillStyle = "#fff";
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                ctx.drawImage(img, 0, 0, width, height);
                //进行最小压缩
                let ndata = canvas.toDataURL("image/jpeg", 0.1);
                return ndata;
            },
            dataURLtoBlob(base64Data) {
                var byteString;
                if (base64Data.split(",")[0].indexOf("base64") >= 0)
                    byteString = atob(base64Data.split(",")[1]);
                else byteString = unescape(base64Data.split(",")[1]);
                var mimeString = base64Data
                    .split(",")[0]
                    .split(":")[1]
                    .split(";")[0];
                var ia = new Uint8Array(byteString.length);
                for (var i = 0; i < byteString.length; i++) {
                    ia[i] = byteString.charCodeAt(i);
                }
                return new Blob([ia], { type: mimeString });
            },
            dataURLtoFile(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});
            },
            post(rawFile) {
                const { uid } = rawFile;
                const options = {
                    headers: this.my,
                    withCredentials: this.withCredentials,
                    file: rawFile,
                    data: '',
                    filename: this.name,
                    action: this.action,
                    onProgress: e => {
                        this.onProgress(e, rawFile);
                    },
                    onSuccess: res => {
                        this.onSuccess(res, rawFile);
                        delete this.reqs[uid];
                    },
                    onError: err => {
                        this.onError(err, rawFile);
                        delete this.reqs[uid];
                    }
                };
                const req = this.httpRequest(options);
                this.reqs[uid] = req;
                if (req && req.then) {
                    req.then(options.onSuccess, options.onError);
                }
            },
            beforeAvatarUpload(file) {

                const isJPG = file.type === 'image/jpeg';
                const isLt2M = file.size / 1024 / 1024 < 2;

                if (!isJPG) {
                    this.$message.error('上传头像图片只能是 JPG 格式!');
                    return 0;
                }
                if (!isLt2M) {
                    this.$message.error('上传头像图片大小不能超过 2MB!');
                    return 0;
                }
                let self=this;
                if (!file || !window.FileReader) return;
                let reader = new FileReader();
                reader.readAsDataURL(file);
                reader.onloadend = function() {
                    let result = this.result;
                    let img = new Image();
                    img.src = result;
                    img.onload = function() {
                        let data = self.compress(img);
                        self.imgUrl = result;
                        let blob = self.dataURLtoBlob(data);
                        self.tempfile=self.dataURLtoFile(data,file.name);
                        var formData = new FormData();
                        formData.append("pic", blob);
                        let config = {
                            headers:{'Content-Type':'multipart/form-data'}
                        }
                        self.$http.post('' + LOCALHOST_URL + '/api/uploadPic',formData,config).then((response) => {
                                if(response.data.success=true) {
                                    self.$message({
                                        type: 'success',
                                        message: '修改成功!'
                                    });
                                    self.imageUrl = URL.createObjectURL(formData.get('pic'));
                                }
                            }, (response) => {
                                console.log(response)
                            }
                        )
                    }
                }
            },

3、api
router.post('/api/uploadPic',upload.single('pic'),function (req, res) {
    let file = req.file;
    let tmp_path = file.path;
    let target_path = './upload/pic/' + file.filename + '.jpg';
    let resBody={};

    console.log(file);

    fs.rename(tmp_path, target_path, function (err) {
        if (err) throw err;
        fs.unlink(tmp_path, function () {
        })
    });

    let id = req.api_user.id;
    let url='https://dc17.xin/api/uploadpic/'+file.filename+'.jpg';       //TODO 上传至服务器后修改
    connection.query('UPDATE user set thumb=?  WHERE id =? ',[url,id], function (err) {
        if (err) {
            resBody.error = 500;
            return res.send(resBody);
        }
        else {
            resBody.success = true;
            return res.send(resBody);
        }
    })
});

注意事项:

         参考(https://www.jianshu.com/p/7a41b080a9d2)提到了上传的formdata的headers必须要是{ "Content-Type": "multipart/form-data" }

         不然不能被multer插件拦截

原文地址:https://www.cnblogs.com/penkgao/p/8484107.html