Now there are more and more mobile Web pages, many active pages are involved in the difficult problem of uploading pictures, and the user’s mobile phone has a high pixel, a picture is 5~10M, if you want to upload multiple pictures at a time, the first time will take too much time. The second is that the user’s flow will also cost a lot, and if the front-end image compression can be very good to avoid these two problems. My basic idea is that after the user adds the file through the input[file] input box, it reads the picture information, draws the picture on the Canvas, and then converts it into a picture to achieve compression upload.

Core API

canvas.getContext('2d').drawImage(img, dx, dy, dWidth, dHeight)

  • Img image object
  • Dx will draw the picture tocanvasThe x coordinate of the top left corner of the picture on the canvas
  • Dy draws the picture tocanvasThe y coordinate of the top left corner of the picture on the canvas
  • DWidth draws the image tocanvasThe width of the picture to draw
  • DHeight draws the image tocanvasThe height of the picture to be drawn

The implementation process

  1. The user clicksinput[file]The logic after selecting the image
<input type="file" accept="image/*" onchange="uploadImageHandle"/>

<script>
	functionUploadImageHandle (e) {var reader = new FileReader(), img = new Image(); // Read the information of the uploaded image (lastModified, lastModifiedDate, name, size,typeVar file = e.targe.files [0]; Var fileType = file.type; Var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d'); // MDN: this method reads the specified Blob or File object. When the read operation is complete, // readyState becomes DONE and the loadend event is triggered, and the result property contains a string in data:URL format (Base64 encoded) representing the contents of the read file. // That is, convert the File object to the base64-bit string read.readasdataURL (File); // The previous step is asynchronous, the onload event is executed after reading, and the string of base64 is in e.target.rusultfunction(e) {// get the image dom img.src = e.target.result; console.log( img ) } img.onload =functionVar originWidth = this.width; var originHeight = this.height; Var maxWidth = 800, maxHeight = 800; Var targetWidth = originWidth, targetHeight = originHeight; // The image size exceeds the 800x800 limitif (originWidth > maxWidth || originHeight > maxHeight) {
          if(originWidth/originHeight > maxWidth/maxHeight) { targetHeight = Math.round(maxWidth * (originHeight / originWidth)); }else{ targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / originHeight)); } // Canvas to scale canvas. Width = targetWidth; canvas.height = targetHeight; // Clear the canvas context.clearRect(0, 0, targetWidth, targetHeight); DrawImage (img, 0, 0, 800, 800); drawImage(img, 0, 0, 800); / / the canvas into base64 format and remove head var base64 = canvas. ToDataURL (fileType.) replace (/ ^ data: image \ / (jpeg | JPG | PNG | GIF); base64,/,' '); // Upload base64. If you want to upload a picture, just repeat the above steps and set base64 to SRC. Of course, the header needs to be removed before the axios.post('https://yourdomain.com/api/xxx', {
      	imageSrc: base64
      }).then(res => {
      	console.log( res )
      }).catch(err => {
      	console.log( err )
      })
	}
</script>
Copy the code

So, you can compress and upload images, which is actually pretty easy, so you don’t have a live preview, but now that you’ve FileReader, it’s pretty easy to preview, and that’s all for today, image uploads are getting used more and more, just for the record, You don’t have to go through the files every time you do it.