Image compression on the front end

Preface

Image compression has a wide range of applications in many interactive scenarios. The html5 standard has not yet become popular. Before image compression is mainly achieved through server-side programming, with the rapid development of browsers, support for many advanced attributes has enabled front-end technology to achieve the same functions. .This article takes an in-depth study of how front-end technology compresses and generates images from a practical perspective.

The case rendering is as follows. Open a local picture by selecting the file button and preview it on the page. Then select the compression rate, the compressed picture effect will be displayed below, and finally click Generate to download the compressed picture.

Full Demo address

 

Function realization

  html structure

                                           

                             

updateFile method implementation

The updateFile function is triggered when the user clicks the button to upload a local picture, and file is the file object of the uploaded picture.

 /**
   * 给input绑定事件
   */
  async function updateFile(e) {
    const file = e.target.files[0];

    if (!verify(file)) {
      //参数校验
      return false;
    }

    const base64Code = await getBase64(file); //获取base64编码

    placeImg(base64Code); //放置图片
  }

The verify function can know the type and size of the file by obtaining the file object, so as to formulate some specifications to restrict upload behavior.

  /**
   * 参数校验
   * @param {*} file
   */
  function verify(file) {
    const { size, type } = file;
    if (size > 5 * 1024 * 1024) {
      alert('上传图片大小不能超过5M');
      return false;
    }
    if (!img_types.includes(type)) {
      alert('请上传图片');
      return false;
    }
    return true;
  }

The getBase64 function uses the FileReader AP to convert pictures into base64 encoding

  function getBase64(file) {
    return new Promise((resolve) => {
      const fileReader = new FileReader();
      fileReader.onload = (e) => {
        resolve(e.target.result);
      };
      fileReader.readAsDataURL(file);
    });
  }

The main function of the placeImg function is to calculate the appropriate width and height of the preview image (original image) and render it on the page. The code is base64 encoding, and the target is the dom element that is ready to hold the preview image. Its width and height are the allowable settings of the image. The maximum width and maximum height of the image object image can get the original width and height of the image through naturalWidth and naturalHeight. First divide the original width of the image by the original height to get the aspect ratio radio. If the original aspect ratio is larger, take the maximum width max_width The value that is smaller than the original naturalWidth of the picture is assigned to width, and the width uses the aspect ratio radio to calculate the height. If it is found that the height is still greater than the maximum height at this time, then the aspect ratio needs to be further reduced. Finally, the width and height can be obtained. Ensure that the size of the image will not overflow the outer dom container, but also display the aspect ratio without distortion. Finally, execute target.appendChild(image); to display the preview image with the set width and height on the page.

 /**
   * 给图片设置合适的宽高放置在容器中
   */
  function placeImg(code) {
    const target = document.getElementById('original');
    const max_width = parseInt(getComputedStyle(target).width);
    const max_height = parseInt(getComputedStyle(target).height);
    let width, height;
    const image = new Image();
    image.src = code;
    image.onload = () => {
      const naturalWidth = image.naturalWidth;
      const naturalHeight = image.naturalHeight;
      const radio = naturalWidth / naturalHeight;
      if (radio >= 1) {
        //宽比高大
        width = naturalWidth < max_width ? naturalWidth : max_width;
        height = (width * 1) / radio;
        if (height > max_height) {
          height = max_height;
          width = height * radio;
        }
      } else {
        height = naturalHeight < max_height ? naturalHeight : max_height;
        width = height * radio;
        if (width > max_width) {
          width = max_width;
          height = (width * 1) / radio;
        }
      }
      width = parseInt(width);
      height = parseInt(height);
      image.style.width = `${width}px`;
      image.style.height = `${height}px`;
      target.innerHTML = '';
      target.appendChild(image);
      img = image; //将预览图对象赋值给全局变量img
      compress();
    };
  }

The preview image has been rendered on the page. Next, the compressed image will be displayed below the preview image. The compress function realizes this function. The value is the currently selected value of the select tag, that is, the compression ratio to be set for the image. Create a canvas tag in the memory, Set its width and height to the width and height of the preview object, and draw the preview image onto the canvas. Finally, through a key API canvas.toDataURL, the compressed base64 encoding of the image can be generated, and the second parameter of canvas.toDataURL is filled in. The input is the compression ratio. The compressed base64 code is assigned to the Image object and rendered under the page, so the compressed image is also displayed smoothly.

/**
   * 压缩图片
   */
  function compress() {
    if (!img) { //img是预览图对象
      return false;
    }
    const value = Number(document.getElementById('sel').value);
    const canvas = document.createElement('CANVAS');
    const w = img.width,
      h = img.height;
    canvas.width = w;
    canvas.height = h;
    var ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0, w, h);
    const code = canvas.toDataURL('image/jpeg', value);
    const image = new Image();
    image.src = code;
    image.onload = () => {
      const des = document.getElementById('production');
      des.innerHTML = '';
      des.appendChild(image);
      compress_img = image;
    };
  }

Generate picture

 Compress_img is a compressed image object. When the user clicks to generate, the generate function will trigger. It first creates an A tag, assigns the base64 encoding of the compressed image to the href attribute, and adds a value to the download attribute, which corresponds to The name of the image after downloading. Finally, the click behavior of the A tag is executed to trigger the download.

  /**
   * 下载图片
   * @param {*}
   */
  function generate() {
    if (!compress_img) {
      return false;
    }
    const a = document.createElement('A');
    a.href = compress_img.src;
    a.download = 'download';
    a.click();
  }

 

to sum up

The process of the entire case starts with the user uploading the picture. First, it will judge whether the uploaded file meets the specifications, then convert the picture to base64 encoding and set the appropriate width and height to display on the local web page. The original picture has been rendered smoothly, and then To render the compressed image below. Create a new canvas object in memory, render the original image to the canvas, and compress the image through a key API canvas.toDataURL, which will return the base64 encoding of the compressed image, and then compress it The picture is also displayed on the page. Finally, when the user clicks on generate, the compressed picture can be downloaded to the local smoothly.

Guess you like

Origin blog.csdn.net/brokenkay/article/details/107865282