前端压缩图片为指定宽高

压缩图片原理

  1. 通过原生的input标签拿到要上传的图片文件
  2. 将图片文件转化成img元素标签
  3. 在canvas上压缩绘制该HTMLImageElement
  4. 将图片转化为一个包含图片展示的data URI,即图片被转换成base64编码的字符串

实现

通过原生的input标签拿到上传的图片文件

  1. css部分
    <input
      ref="image"
      type="file"
      accept="image/*"
      @change="getFile"
    />
    
  2. 图片上传后通过以下代码拿到上传的图片文件,这里拿到的为FileList文件对象数组,如下图所示。因为我们这里是单文件上传,因此直接取数组中第一个file对象就是我们上传的图片文件
    this.$refs.image.files[0]
    
    在这里插入图片描述

将图片文件转化成img元素标签

  1. 由于通过input拿到的文件是file对象类型的,在压缩之前需要转化为img对象,通过以下方法即可

    fileToImg (file) {
          
          
      return new Promise((resolve, reject) => {
          
          
        const img = new Image()
        const reader = new FileReader()
        reader.onload = function (e) {
          
          
          img.src = e.target.result
        }
        reader.onerror = function (e) {
          
          
          reject(e)
        }
        reader.readAsDataURL(file)
        img.onload = function () {
          
          
          resolve(img)
        }
        img.onerror = function (e) {
          
          
          reject(e)
        }
      })
    }
    

在canvas上压缩绘制该HTMLImageElement,将图片转换成base64编码的字符串

  1. 将图片转化为img对象后,就可以创建canvas对象,在canvas上压缩绘制合适宽高的图片。这里分为两种情况:

    1. 将图片压缩为指定高度
    /**
     * 压缩图片
     * @param img 被压缩的img对象
     * @param height 触发压缩的图片固定高度
     */
    compressImgHeight (img, height) {
          
          
      return new Promise((resolve) => {
          
          
      	// 创建canvas对象
        const canvas = document.createElement('canvas')
    
        const context = canvas.getContext('2d')
    	// 获取上传的img图片对象的宽度和高度
        const {
          
           width: originWidth, height: originHeight } = img
    
        // 绘制图片的高度
        canvas.height = height
    	// 根据绘制图片的高度,等比例计算图片的宽度
        canvas.width = (originWidth * canvas.height) / originHeight
    
        // 将img绘制到画布上
        context.drawImage(img, 0, 0, canvas.width, canvas.height)
    
        // 转为一个包含图片展示的data URI,即图片被转换成base64编码的字符串,格式为jpeg
        // 0.8为图片质量,区间为0~1,默认0.92
        resolve(canvas.toDataURL('image/jpeg', 0.8))
      })
    },
    
    1. 将图片压缩为指定宽度
    /**
     * 压缩图片
     * @param img 被压缩的img对象
     * @param width 触发压缩的图片固定宽度
     */
    compressImgHeight (img, width) {
          
          
      return new Promise((resolve) => {
          
          
      	// 创建canvas对象
        const canvas = document.createElement('canvas')
    
        const context = canvas.getContext('2d')
    	// 获取上传的img图片对象的宽度和高度
        const {
          
           width: originWidth, height: originHeight } = img
    
        // 绘制图片的宽度
        canvas.width = width
    	// 根据绘制图片的宽度,等比例计算图片的高度
        canvas.height = (originHeight * canvas.width) / originWidth
    
        // 将img绘制到画布上
        context.drawImage(img, 0, 0, canvas.width, canvas.height)
    
        // 转为一个包含图片展示的data URI,即图片被转换成base64编码的字符串,格式为jpeg
        // 0.8为图片质量,区间为0~1,默认0.92
        resolve(canvas.toDataURL('image/jpeg', 0.8))
      })
    }
    

总结

  1. 将以上代码进行总结
    // css部分
    <input
      ref="image"
      type="file"
      accept="image/*"
      @change="getFile"
    />
    
    
    // js部分
    getFile () {
          
          
      this.readImg(this.$refs.image.files[0]).then(res => {
          
          
      	// 压缩图片为指定宽度
        this.compressImgHeight(res, 300).then(img => {
          
          
          // 输出压缩后的图片base64
          console.log(img)
        })
      })
    }
    
    /**
     * 将图片file对象转化为img对象
     * @param file 图片file对象
     */
    fileToImg (file) {
          
          
      return new Promise((resolve, reject) => {
          
          
        const img = new Image()
        const reader = new FileReader()
        reader.onload = function (e) {
          
          
          img.src = e.target.result
        }
        reader.onerror = function (e) {
          
          
          reject(e)
        }
        reader.readAsDataURL(file)
        img.onload = function () {
          
          
          resolve(img)
        }
        img.onerror = function (e) {
          
          
          reject(e)
        }
      })
    },
    
    /**
     * 压缩图片为指定宽度
     * @param img 被压缩的img对象
     * @param width 触发压缩的图片固定宽度
     */
    compressImgWidth (img, width) {
          
          
      return new Promise((resolve) => {
          
          
      	// 创建canvas对象
        const canvas = document.createElement('canvas')
    
        const context = canvas.getContext('2d')
    	// 获取上传的img图片对象的宽度和高度
        const {
          
           width: originWidth, height: originHeight } = img
    
        // 绘制图片的宽度
        canvas.width = width
    	// 根据绘制图片的宽度,等比例计算图片的高度
        canvas.height = (originHeight * canvas.width) / originWidth
    
        // 将img绘制到画布上
        context.drawImage(img, 0, 0, canvas.width, canvas.height)
    
        // 转为一个包含图片展示的data URI,即图片被转换成base64编码的字符串,格式为jpeg
        // 0.8为图片质量,区间为0~1,默认0.92
        resolve(canvas.toDataURL('image/jpeg', 0.8))
      })
    },
    
    /**
     * 压缩图片为指定高度
     * @param img 被压缩的img对象
     * @param height 触发压缩的图片固定高度
     */
    compressImgHeight (img, height) {
          
          
      return new Promise((resolve) => {
          
          
      	// 创建canvas对象
        const canvas = document.createElement('canvas')
    
        const context = canvas.getContext('2d')
    	// 获取上传的img图片对象的宽度和高度
        const {
          
           width: originWidth, height: originHeight } = img
    
        // 绘制图片的高度
        canvas.height = height
    	// 根据绘制图片的高度,等比例计算图片的宽度
        canvas.width = (originWidth * canvas.height) / originHeight
    
        // 将img绘制到画布上
        context.drawImage(img, 0, 0, canvas.width, canvas.height)
    
        // 转为一个包含图片展示的data URI,即图片被转换成base64编码的字符串,格式为jpeg
        // 0.8为图片质量,区间为0~1,默认0.92
        resolve(canvas.toDataURL('image/jpeg', 0.8))
      })
    }
    

猜你喜欢

转载自blog.csdn.net/lhh_gxx/article/details/128704823
今日推荐