前端JS实现图片压缩

611 阅读1分钟

压缩思路

涉及到压缩,个人想到的实现方式是利用Canvas的绘图能力,通过调节分辨率或者绘图质量来达到压缩的目的

  • 获取上传input控件中的file对象
  • 将图片转换成base64格式
  • 利用Canvas的转换压缩,其中会使用drawImage和toDataURL 这两个API,前者是调节分辨率,后者则是调节绘图质量(只有 jpeg或者webp)
  • 转换后生成新的图片进行输出

优缺点

  • 优点:实现简单,参数可配置化,可以自定义图片的尺寸,裁剪的区域等等
  • 缺点:只有jpeg、webp的图可通过toDataURL 配置质量进行输出

代码实现

<template>
  <div class="page">
      <input type="file" id="input-img" @change="compress" />
  <div>
 </template>
<script>
export default {
  data(){
      return {
          imgBase64:''
      }
  },
  methods:{
      compress(){
              const fileObj = document.querySelector('#input-img').files[0];
              const fileNames = fileObj.name.split('.');
              const type = fileNames[fileNames.length-1];
              this.handleCompressImage(fileObj,type)
      },
      handleCompressImage(img, type){
             let vm = this;
             // 读取文件
              reader.readAsDataURL(img);
              reader.onload = function(e) {
                let image = new Image(); //新建一个img标签
                console.log(e.target.result);
                image.src = e.target.result;
                image.onload = function() {
                  let canvas = document.createElement('canvas');
                  let context = canvas.getContext('2d');
                  // 定义 canvas 大小,也就是压缩后下载的图片大小
                  let imageWidth = image.width; //压缩后图片的大小
                  let imageHeight = image.height;
                  canvas.width = imageWidth;
                  canvas.height = imageHeight;

                  // 图片不压缩,全部加载展示
                  context.drawImage(image, 0, 0);
                  // 图片按压缩尺寸载入
                  // let imageWidth = 500; //压缩后图片的大小
                  // let imageHeight = 200;
                  // context.drawImage(image, 0, 0, 500, 200);
                  // 图片去截取指定位置载入
                  // context.drawImage(image,100, 100, 100, 100, 0, 0, imageWidth, imageHeight);
                  vm.imgBase64 = canvas.toDataURL(`image/${type}`,0.5);
        };
      }

      
  }
 }