elementUI upload checks the width and height of the picture

Posted by pestilence669 on Tue, 24 Sep 2019 14:12:08 +0200

Preface

In the process of using vue+elementUI, I encountered a problem: upload checks the width and height of the picture

At first, I went directly to Baidu google and found that there was no such problem. This should be a very common requirement. Why didn't element ation come true? Maybe it's very simple. There are no such problems on the internet. I went to GitHub's issue to see that there are similar problems, but there is no systematic solution, cool.

If you can't find it, you have to make trouble for yourself.

thinking

If you want to make a wide college experience of pictures, you need to get the width and height information of pictures: image.onload

The onload event is executed immediately after the image is loaded.

let image = new Image();
image.onload = function() {
    let width = image.width;
    let height = image.height;
};
image.src = "images/bg.jpg";

When you get the information, you can compare it. For example, I need a 750*420 size picture.

let width = 750;  //image width
let height = 420; //Picture height
let image = new Image();
image.onload = function() {
    let isSize = image.width == width && image.height == height;
    if (!isSize) {
        that.$message.error("Uploaded head image size does not match,It can only be 750.*420");
    }
};
image.src = "images/bg.jpg";

Now I want to get the uploaded picture information.

beforeAvatarUpload(file) {
    // Preprocessing Function for Uploading Pictures
    let width = 750;  //image width
    let height = 420; //Picture height
    let _URL = window.URL || window.webkitURL;
    let image = new Image();
    img.onload = function() {
        let isSize = image.width == width && image.height == height;
        if (!isSize) {
            that.$message.error("Uploaded head image size does not match,It can only be 750.*420");
        }
        return isSize;
    };
    img.src = _URL.createObjectURL(file);
}

Now isSize has been reassigned, with the right hints, but only a flash, and successfully uploaded, very depressed, step by step began debugger, found that the final return can still be returned, but do not know why, and then began to google, found that my thinking is wrong.

Take a close look at this article on the Nuggets JS Application Scenario (Promise => Picture Upload) It is found that upload people really want a promise, you give isSize a boolean value directly, and finally return out is of no use, which explains why the error message can be popped up and uploaded successfully. This is just the implementation method.

Let's look at the source code, it's a bit of an eyebrow.

upload(rawFile) {
    this.$refs.input.value = null;
    if (!this.beforeUpload) {
    return this.post(rawFile);
    }
    const before = this.beforeUpload(rawFile);
    if (before && before.then) {
    before.then(processedFile => {
        const fileType = Object.prototype.toString.call(processedFile);
        if (fileType === '[object File]' || fileType === '[object Blob]') {
        if (fileType === '[object Blob]') {
            processedFile = new File([processedFile], rawFile.name, {
            type: rawFile.type
            });
        }
        for (const p in rawFile) {
            if (rawFile.hasOwnProperty(p)) {
            processedFile[p] = rawFile[p];
            }
        }
        this.post(processedFile);
        } else {
        this.post(rawFile);
        }
    }, () => {
        this.onRemove(null, rawFile);
    });
    } else if (before !== false) {
         this.post(rawFile);
    } else {
         this.onRemove(null, rawFile);
    }
},

This discovers that this.beforeUpload is a real promise. You have to return a promise to others. Simple boolean value is useless, because there are many implementations of promise in people's homes. This makes it clear that there is a final way to push the boat along the river. After a variety of tests, it is indeed possible.

Final Edition Code

beforeAvatarUpload(file) {
    // Preprocessing Function for Uploading Pictures
    const isJPG =
        file.type === "image/jpeg" ||
        file.type === "image/png" ||
        file.type === "image/gif";
    const isLt2M = file.size / 1024 / 1024 < 2;
    let that = this;
    let isAllow = false;
    if (!isJPG) {
        this.$message.error("Uploading avatar pictures can only be jpg,png,gif format!");
    }
    if (!isLt2M) {
        this.$message.error("Upload head image size should not exceed 2 MB!");
    }
    const isSize = new Promise(function(resolve, reject) {
        let width = 750;
        let height = 420;
        let _URL = window.URL || window.webkitURL;
        let image = new Image();
        image.onload = function() {
          let valid = image.width == width && image.height == height;
          valid ? resolve() : reject();
        };
        image.src = _URL.createObjectURL(file);
    }).then(
        () => {
          return file;
        },
        () => {
          this.$message.error("Uploaded head image size does not match,It can only be 750.*420!");
          return Promise.reject();
        }
      );
    return isJPG && isLt2M && isSize;
}

Looking at the final version of the code, we find that it is really very simple. We are often led astray by the inherent thinking. In fact, we are not very good at it. In the future, we should pay more attention to the foundation, dig more details, see the big from the small, practice the internal work, and encourage each other.

Topics: Front-end Google Vue github