Image compression and upload

1. Compression method public js

/** 图片压缩,默认同比例压缩
 *  @param {Object} fileObj
 *  图片对象
 *  回调函数有一个参数,base64的字符串数据
 */
 export function compress(fileObj, callback) {
  try {
    const image = new Image()
    image.src = URL.createObjectURL(fileObj)
    image.onload = function() {
      const that = this
      // 默认按比例压缩
      let w = that.width
      let h = that.height
      const scale = w / h
      w = fileObj.width || w
      h = fileObj.height || (w / scale)
      let quality = 0.7 // 默认图片质量为0.7
      // 生成canvas
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      // 创建属性节点
      const anw = document.createAttribute('width')
      anw.nodeValue = w
      const anh = document.createAttribute('height')
      anh.nodeValue = h
      canvas.setAttributeNode(anw)
      canvas.setAttributeNode(anh)
      ctx.drawImage(that, 0, 0, w, h)
      // 图像质量
      if (fileObj.quality && fileObj.quality <= 1 && fileObj.quality > 0) {
        quality = fileObj.quality
      }
      // quality值越小,所绘制出的图像越模糊
      const data = canvas.toDataURL('image/jpeg', quality)
      // 压缩完成执行回调
      const newFile = convertBase64UrlToBlob(data)
      callback(newFile)
    }
  } catch (e) {
    console.log('压缩失败!')
  }
}
function convertBase64UrlToBlob(urlData) {
  const bytes = window.atob(urlData.split(',')[1]) // 去掉url的头,并转换为byte
  // 处理异常,将ascii码小于0的转换为大于0
  const ab = new ArrayBuffer(bytes.length)
  const ia = new Uint8Array(ab)
  for (let i = 0; i < bytes.length; i++) {
    ia[i] = bytes.charCodeAt(i)
  }
  return new Blob([ab], { type: 'image/png' })
}

2. el-upload upload component

<el-upload
  name="file"
  class="upload"
  list-type="picture-card"
  action="#"
  accept="image/jpeg, image/jpg, image/png"
  :file-list="fiilList"
  :on-change="uploadChange"
  :multiple="false"
  :limit="1"
  :auto-upload="false"
>

3. js part

import { compress } from '@/utils/compress.js'
import { AjaxUploadImg } from '@/utils/uploadImg.js'
uploadChange(file, fileList) {
      const _this = this;
      const isLt1M = file.size / 1024 / 1024 < 1;
      // 上传图片不能大于1M
      if (!isLt1M) {     console.log('上传图片不能大于1M')     return false;
      } else {
        const isLt04 = file.size / 1024 / 1024 > 0.4;
        // 上传图片大于400KB再压缩
        if(isLt04) {
          // 压缩图片
          compress(file.raw, function(val) {
            let params = {
              file: val,
              type: 1,
              id: _this.officialInfo.id
            }
            _this.uploadImg(params, file.name, fileList);
          })
        } else {
          let params = {
            file: file.raw,
            type: 1,
            id: _this.officialInfo.id
          }
          _this.uploadImg(params, file.name, fileList);
        }
      }
    },
    uploadImg(params, fileName, fileList) {
      const _this = this;
      AjaxUploadImg(_this.uploadUrl, params, fileName, function(res) {
        let data = JSON.parse(res)
        if(data.code==200){
          console.log('上传成功!')
        } else {
          _this.$message.error("图片上传失败!");
        }
      });
    },

Encapsulated request method: uploadImg.js

/** 
 * 原生AJAX请求
 * 上传图片
 * url     服务器地址
 * data    传递的参数
 * imgName 图片名称
 * fn      返回的数据
 */
// bus为vue对象
import bus from "./bus";
export function AjaxUploadImg(url, data, imgName, fn) {
  let formData = new FormData();
  for (const key in data) {
    if(key == 'file'){
      // 判断是否为blob对象
      if(data[key] instanceof Blob){
        // blob对象转file对象
        let files = new window.File([data[key]], imgName)
        formData.append('file', files);
      } else {
        formData.append('file', data[key]);
      }
    } else {
      formData.append(key, data[key]);
    }
  }
  // 建立请求
  var xhr = new XMLHttpRequest();
  xhr.open("POST", url, true);
  xhr.setRequestHeader("Authorization", "Bearer " + bus.$cookieGet("TOKEN"));
  xhr.onreadystatechange = function() {
    if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
      fn.call(this, xhr.responseText);
    }
  };
  xhr.send(formData);
}

PS: The public js of the compression method comes from https://blog.csdn.net/liona_koukou/article/details/84860899

Guess you like

Origin blog.csdn.net/qq_42660374/article/details/129589074