We usually encounter such situations when uploading pictures. One is that the back-end interface limits the size of uploaded pictures, or even if the back-end does not limit the size, because the picture is too large and the front-end rendering takes too long, resulting in poor page loading experience. Therefore, it is necessary for us to compress the uploaded pictures.

This article is included in gitthub: github.com/Michael-lzg…

This paper mainly includes the following processes:

  • By the userinputBox selection picture
  • useFileReaderPreview images
  • Draw the picture tocanvasThe canvas
  • usecanvasCanvas ability for image compression
  • I’m going to compressBase64(DataURL)Format data intoBlobObject upload

Input tag to get the image

Set the type attribute of the input tag to File to allow the user to select files, set accept to limit the selected file type, and bind the onchange event to obtain the selected file

<input type="file" accept="image/*" onchange="loadFile(event)"
Copy the code

FileReader

What is a FileReader

The FileReader object allows a Web application to asynchronously read the contents of a File (or raw data buffer) stored on the user’s computer, using a File or Blob object to specify which File or data to read.

Two common FileReader methods are as follows:

  • FileReader.onload: handlingloadEvents. That is, the hook is triggered when the reading operation is completed. The hook function can be used to complete such operations as preview after reading the picture, or secondary processing of the picture content after reading the picture.
  • FileReader.readAsDataURL: read method, and after reading,resultProperty will returnData URLFormat (Base64 encoded), representing the image content.

In the image uploading, we can read the file through readAsDataURL() method, and get the Base64(DataURL) format data of the image through the result attribute, and then realize the function of image preview through the data

<div class="container">
  <input type="file" accept="image/*" onchange="loadFile(event)" />
</div>
<script>
  const loadFile = function (event) {
    let file =  event.target.files[0]
    const reader = new FileReader()
    reader.onload = function () {
      console.log(reader.result)
      ...
    }
    reader.readAsDataURL(file)
  }
</script>
Copy the code

Canvas compressed image

This is the core of the image upload compression, we first use CanvasRenderingContext2D. The drawImage () method will upload image files on the canvas mapped, Canvas.todataurl () is then used to convert the picture information on the Canvas into base64(DataURL) format data.

drawImage()

The drawImage() method draws an image, canvas, or video on a canvas. The drawImage() method can also draw parts of an image and/or increase or decrease the size of the image. The following parameters

  • Img specifies the image, canvas, or video to use.
  • Sx is optional. The x position at which the shear began.
  • Sy is optional. The y position where the shear started.
  • Swidth optional. The width of the clipped image.
  • Sheight optional. The height of the clipped image.
  • X Places the x coordinate position of the image on the canvas.
  • Y The y-coordinate position of the image placed on the canvas.
  • Width is optional. The width of the image to use. (Stretch or zoom out image)
  • Height is optional. The height of the image to use. (Stretch or zoom out image)
var cas = document.querySelector('canvas')
var ctx = cas.getContext('2d')
// Create the image object first
var img = new Image()
img.src = './images/1.jpg'

// After the image is loaded
img.onload = function () {
  ctx.drawImage(img, 206.111.32.38.100.100.32.38)}Copy the code

Canvas.toDataURl()

The canvas.todataURL () method can convert the information on Canvas Canvas to image information in Base64 (DataURL) format, the image representation form of pure characters. This method accepts two parameters:

  • mimeType(Optional): Indicates the image to be convertedmimeTypeType. The default value isimage/pngIt could also beimage/jpeg.image/webpAnd so on.
  • quailty(Optional) : Quality Indicates the image quality of the conversion. The range is 0 to 1. The imagemimeTypeNeed to beimage/jpegorimage/webp, othermimeTypeValue is invalid. The default compression quality is 0.92.
var canvas = document.createElement('canvas')
canvas.toDataURL("image/jpeg" 0.8)
Copy the code

Here, we first to canvas compression image code

function compress(base64, quality, mimeType) {
  let canvas = document.createElement('canvas')
  let img = document.createElement('img')
  img.crossOrigin = 'anonymous'
  return new Promise((resolve, reject) = > {
    img.src = base64
    img.onload = (a)= > {
      let targetWidth, targetHeight
      if (img.width > MAX_WIDTH) {
        targetWidth = MAX_WIDTH
        targetHeight = (img.height * MAX_WIDTH) / img.width
      } else {
        targetWidth = img.width
        targetHeight = img.height
      }
      canvas.width = targetWidth
      canvas.height = targetHeight
      let ctx = canvas.getContext('2d')
      ctx.clearRect(0.0, targetWidth, targetHeight) // Clear the canvas
      ctx.drawImage(img, 0.0, canvas.width, canvas.height)
      let imageData = canvas.toDataURL(mimeType, quality / 100)
      resolve(imageData)
    }
  })
}
Copy the code

Convert Base64 to a file

  • throughwindow.atobbase-64String decoded tobinaryStringBinary text;
  • willbinaryStringStructure ofmultipart/form-dataFormat;
  • withUint8ArraymultipartFormat the binary text intoArrayBuffer.
function dataUrlToBlob(base64, mimeType) {
  let bytes = window.atob(base64.split(', ') [1])
  let ab = new ArrayBuffer(bytes.length)
  let ia = new Uint8Array(ab)
  for (let i = 0; i < bytes.length; i++) {
    ia[i] = bytes.charCodeAt(i)
  }
  return new Blob([ab], { type: mimeType })
}
Copy the code

Upload the image to the server

  • To create aFormData,blobAppend to theFormDatainside
  • Request the server interface to submit the image
function uploadFile(url, blob) {
  let formData = new FormData()
  let request = new XMLHttpRequest()
  formData.append('image', blob)
  request.open('POST', url, true)
  request.send(formData)
}
Copy the code

Ps: In the actual development, whether we should convert the image into FormData form and upload it to the server depends on the specific business needs. We can upload the picture to Tencent Cloud and directly return an ‘HTTPS. Xxx. JGP’ picture URL for uploading.

Recommend the article

Build a VuE-CLI4 + WebPack mobile framework (out of the box)
Build from scratch to optimize a vue-CLI-like scaffolding
Encapsulate a TOAST and Dialog component and publish it to NPM
Build a WebPack project from scratch
Summary of several webpack optimization methods
Summary of advanced application of VUE knowledge system
Summarize the practical skills of vUE knowledge system
Summarize the basic introduction to vUE knowledge system
Summary of mobile H5 development tips.

Concerned about my public number irregularly share front-end knowledge, progress with you!