vue图片压缩

  • 需求
  • 解决方式
  • 一、安装依赖
  • 二、根据图片URL进行压缩完整代码
  • 1.将图片URL转为转为file
  • 2.页面中使用
  • 三、上传文件时进行压缩



需求

根据图片的URL或者上传图片时将图片进行压缩到10KB


解决方式

使用image-conversion进行压缩


一、安装依赖

npm i image-conversion

页面中引入

import * as imageConversion from 'image-conversion'

使用

//把图片文件作为参数传递到方法中
    beforeAvatarUpload(file) {
      const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
      if (!isJpgOrPng) {
        console.log('上传头像图片只能是 JPG 或 PNG 格式!');
        return false;
      }
      return new Promise((resolve) => {
        // 压缩到100KB,这里的100就是要压缩的大小,可自定义
        imageConversion.compressAccurately(file, 10).then(res => {
          console.log(res)
          resolve(res);
        });
      })
    },

二、根据图片URL进行压缩完整代码

1.将图片URL转为转为file

transferFile.js

function setInitImg(url,callback){
    let img = url;//这里是网上随便找的一张图片
    let _ = this
    let imgRes
    getBase64(img, (dataURL) => {
        imgRes = dataURLtoFile(dataURL,img);
        console.log(imgRes)
        callback(imgRes)
    });
}

function getBase64(url, callback) {
    //通过构造函数来创建的 img 实例,在赋予 src 值后就会立刻下载图片,相比 createElement() 创建 <img> 省去了 append(),也就避免了文档冗余和污染
    var Img = new Image(),
        dataURL = "";
    Img.src = url + "?v=" + Math.random(); // 处理缓存,fix缓存bug,有缓存,浏览器会报错;
    Img.setAttribute("crossOrigin", "Anonymous"); // 解决控制台跨域报错的问题
    Img.onload = function () {
        //要先确保图片完整获取到,这是个异步事件
        var canvas = document.createElement("canvas"), //创建canvas元素
            width = Img.width, //确保canvas的尺寸和图片一样
            height = Img.height;
        canvas.width = width;
        canvas.height = height;
        canvas.getContext("2d").drawImage(Img, 0, 0, width, height); //将图片绘制到canvas中
        dataURL = canvas.toDataURL("image/jpeg"); //转换图片为dataURL
        callback ? callback(dataURL) : null; //调用回调函数
    };
}

function dataURLtoFile(dataurl, filename) {
    //将base64转换为文件,dataurl为base64字符串,filename为文件名(必须带后缀名,如.jpg,.png)
    var arr = dataurl.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, { type: mime });
}

export{ setInitImg}

2.页面中使用

<template>
  <img width="500" :src="conSrc">
  <el-button @click="handleClick">点击</el-button>
</template>
<script>
import * as imageConversion from 'image-conversion'
import {setInitImg} from "./transferFile.js";

export default {
  data() {
    return {
      src: '图片URL',
      conSrc: ''
    }
  },
  methods: {
    handleClick(){
      let that=this
      //先将url转为file
       setInitImg(this.src,file=>{
       //将file进行压缩
        this.beforeAvatarUpload(file).then(res => {
        //最后把file转为base64放到页面上显示
          this.translateBlobToBase64(res,function (e){
            that.conSrc=e
          })
        })
      })
    },
    /**
     * Blob转Base64
     * @param base64 String base64格式字符串
     * @param callback Function 获取转换结果e.target.result后执行的回调函数
     */
    translateBlobToBase64(blob, callback) {
      var reader = new FileReader()
      reader.onload = function (e) {
        callback(e.target.result)
      }
      reader.readAsDataURL(blob)
      //读取后,result属性中将包含一个data:URL格式的Base64字符串用来表示所读取的文件
    },
    //把图片文件作为参数传递到方法中
    beforeAvatarUpload(file) {
      const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
      if (!isJpgOrPng) {
        console.log('上传头像图片只能是 JPG 或 PNG 格式!');
        return false;
      }
      return new Promise((resolve) => {
        // 压缩到100KB,这里的100就是要压缩的大小,可自定义
        imageConversion.compressAccurately(file, 10).then(res => {
          console.log(res)
          resolve(res);
        });
      })
    },
  }
}
</script>
<style scoped>
</style>

结果:

imagemagic convert参数 imageconversionflag_字符串

三、上传文件时进行压缩

此处使用的是element的上传组件,原理都是一样的只不过URL压缩需要先将URL转为file

<template>
  <el-upload
      ref="uploadRef"
      class="upload-demo"
      action=""
      :auto-upload="false"
      :before-upload="handleBeforeUpload"
  >
    <template #trigger>
      <el-button type="primary">select file</el-button>
    </template>

    <el-button class="ml-3" type="success" @click="submitUpload">
      upload to server
    </el-button>

    <template #tip>
      <div class="el-upload__tip">
        jpg/png files with a size less than 500kb
      </div>
    </template>
  </el-upload>
  <img width="500" :src="conSrc">

</template>
<script>
import * as imageConversion from 'image-conversion'
export default {
  data() {
    return {
      src: '图片地址',
      conSrc: ''
    }
  },
  methods: {
    handleBeforeUpload(file) {
      let that=this
      this.beforeAvatarUpload(file).then(res => {
        this.translateBlobToBase64(res,function (e){
          that.conSrc=e
        })
      })
    },
    submitUpload() {
      this.$refs['uploadRef'].submit()
    },
    /**
     * Blob转Base64
     * @param base64 String base64格式字符串
     * @param callback Function 获取转换结果e.target.result后执行的回调函数
     */
    translateBlobToBase64(blob, callback) {
      var reader = new FileReader()
      reader.onload = function (e) {
        callback(e.target.result)
      }
      reader.readAsDataURL(blob)
      //读取后,result属性中将包含一个data:URL格式的Base64字符串用来表示所读取的文件
    },
    //把图片文件作为参数传递到方法中
    beforeAvatarUpload(file) {
      const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
      if (!isJpgOrPng) {
        console.log('上传头像图片只能是 JPG 或 PNG 格式!');
        return false;
      }
      return new Promise((resolve) => {
        // 压缩到100KB,这里的100就是要压缩的大小,可自定义
        imageConversion.compressAccurately(file, 10).then(res => {
          console.log(res)
          resolve(res);
        });
      })
    },


  }
}

</script>
<style scoped>

</style>

结果:

imagemagic convert参数 imageconversionflag_上传_02