Implementation principle:


Create a New Web API FileReader object to read the locally selected image and a new image object to record the basic information about the selected image (e.g. Width,height, etc.), create a “Canvas” tag, use the data recorded by the Image object to redraw an Image on the “Canvas”, and then convert the Image into Base64 encoding, and then process it into Blob type and return it

Here’s how it works (the following example uses the upload component of Element-UI)

When uploading a file, listen for events after the image is selected but before uploading

// This is the code in the template in vue
<el-upload
    ref="upload"<! --
    action="https://jsonplaceholder.typicode.com/posts/"<! --// Support multiple files -->
    :multiple="false"
    name="fileName"<! --/ / data - >
    :data="uploadData"<! --// Upload successful callback -->
    :on-success="uploadSuccess"<! --// Select * from the list of events before the upload.<! --// Callback before upload -->
    :before-upload="uploadHandle"
  ></el-upload>
Copy the code

Listening for the pre-upload callback, the file parameter contains information such as the path of the uploaded file

// File processing before uploading
      uploadHandle(file){
        // check whether the file size is larger than 300kb
        if (file.size <= 327200) {return
        }
        // Return a Promise object
        return new Promise(resolve= > {
          // The object used to read local files
          const reader = new FileReader()
          // Used to store basic information about the selected image
          const image = new Image()
          image.onload = (imageEvent) = > {
            // Create the Canvas tag element
            const canvas = document.createElement('canvas')
            // Specify the type to draw
            const context = canvas.getContext('2d')
            // imgQuality indicates the scale of the imgQuality. I set it to 0.5. It is better to define a variable to make it easier to maintain
            const width = image.width * this.imgQuality  / / 0.5
            const height = image.height * this.imgQuality / / 0.5
            canvas.width = width
            canvas.height = height
            // Clear the canvas rectangle (clear the canvas)
            context.clearRect(0.0,width,height)
            // In the canvas, draw the image at the specified scale
            context.drawImage(image,0.0,width,height)
            // Convert the canvas image to base64
            const dataUrl = canvas.toDataURL(file.type)
            // Convert base64 dataUrl format to BLOB (dataUrlToBlob method below)
            const blobData = this.dataUrlToBlob(dataUrl,file.type)
            // Return blobData for upload
            resolve(blobData)
          }
          // After reading the file, save the path of the image to the new image
          reader.onload = (e= > {image.src = e.target.result})
          // Read the selected file according to the path
          reader.readAsDataURL(file)
        })
      },
      
      // Convert base64 dataUrl format to bloB type
      dataUrlToBlob(dataUrl,type){
        // Use window's ATOB method to decode Base64
        let binary = atob(dataUrl.split(', ') [1])
        let arr = []
        // Switch to Unicode
        for (let i = 0; i < binary.length; i++) {
          arr.push(binary.charCodeAt(i))
        }
        // Create Blob types via Unicode encoding
        return new Blob([new Uint8Array(arr)],{type})
      }
Copy the code