Project requirements: PNG, JPG and GIF. Canvas does not support GIF, so GIF is not processed. Canvas bolb method only supports JPEG. And webP format files for quality compression, and the project needs to be compatible with IE, so only JPEG format files can be saved

First, the benefits of compressing pictures before uploading

  • It can reduce the user’s waiting time and improve the user experience. Currently, the size of the picture file taken by the mobile phone is generally about several meters, and there will be a lag phenomenon when the file is directly uploaded.
  • The storage space on the server can be reduced
  • Again, image resources can also be loaded quickly. Although the current OSS of Ali Cloud has corresponding API to reduce the volume by reducing image quality and other methods, canvas can directly reduce the volume of source files.

Second, implementation ideas and example code

  1. Use the FileReader object to get the Base64 content of the local file that selects the input element with the file
  2. Draw the obtained file on the canvas using context.drawImage
  3. Use Canvas. toBlob to compress images

The sample code

** @param {obj} event uploadImg (event) {// If (! event.target.files[0]) return; let file = event.target.files[0], fileName = file.name.substring(file.name.lastIndexOf(".") + 1).toLowerCase(); If (fileName! = "jpg" && fileName ! = "png" && fileName ! = "gif" ) { this.$store.commit('setPrompt', {status: true, text: 'Please select the correct image format to upload (JPG, PNG, GIF)'}) return} // GIF image format is not processed, If (fileName == 'GIF ') {this.uploadapi (file, file.name)} else {let _this = this; Let reader = new FileReader(), img = new Image(); reader.readAsDataURL(file); // Canvas let canvas = document.createElement('canvas'); let context = canvas.getContext('2d'); Img. onload = function() {// let originWidth = this.width; let originHeight = this.height; canvas.width = originWidth; canvas.height = originHeight; // Clear the canvas context.clearRect(0, 0, originWidth, originHeight); Context. DrawImage (img, 0, 0, originWidth, originHeight); ToBlob (function(blob) {_this.uploadapi (blob, file.name)}, File. type == 'image/ GIF '? 'image/ GIF ': "image/jpeg", 0.6); } reader.onload = function(e) {img.src = e.target.result; }; @param {string} fileName file name ** / uploadApi(file, fileName) { let formData = new FormData() formData.append('img', file, fileName) axios.post('/upload/upload-img', formData, {headers: {'Content-Type': 'multipart/form-data'}}).then((res) => { if (res.data.code == 200) { this.img_list.splice(this.img_list.length, 1, res.data.url) } else { this.$store.commit('setPrompt', {status: true, text: res.data.message}) } }) }Copy the code

Thank you for reading, if there are mistakes, welcome to correct communication.

HTML5 file API plus Canvas image front-end JS compression and upload