element前端如何实现压缩图片功能

发布时间:2023-03-01 17:10:30 作者:iii
来源:亿速云 阅读:172

这篇文章主要讲解了“element前端如何实现压缩图片功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“element前端如何实现压缩图片功能”吧!

实现效果

如下图所示,从 580kb ->  压缩后  150kb

element前端如何实现压缩图片功能

实现步骤

1、父级引入封装文件

//页面上
<el-dialog
      title="压缩图片"
      :visible.sync="compressImgVisible"
      width="700"
      foot-hide
    >
      <uploadImg
      />
    </el-dialog>
 
//js中
data() {
    return {
      compressImgVisible: false,
    }

2、首先实现上传功能,使用el-upload,

封装uploadImg.vue

<template>
  <div class="uploadImgBody">
    <!--上传图片部分-->
    <el-upload
      class="upload-image"
      ref="upload"
      :action="action"
      :headers="headers"
      :multiple="multiple"
      :data="data"
      :name="name"
      :show-file-list="showFileList"
      :drag="drag"
      :accept="accept"
      :list-type="listType"
      :auto-upload="autoUpload"
      :disabled="is_disabled"
 
      :before-upload="beforeUpload"
    >
      <!--弹框展示上传以后的图片-->
      <img
        class="fileImg"
        v-if="mrImgUrl"
        :src="mrImgUrl"
      >
      <div v-else>
        <i class="el-icon-plus"></i>
      </div>
    </el-upload>
  </div>
 
</template>
 
<script>
//element的上传图片,压缩图片组件
export default {
  props:{
    /**
     * 自动上传参数
     * */
    autoUpload:{ // 是否需要选取完自动上传功能
      type: Boolean,
      default: true
    },
    // 默认图片,父级传过来 http开头的文件
    mrImgUrl:{
      type: String,
      default: ''
    },
    action:{//上传的地址
      type: String,
      default: ''
    },
    headers: {//设置上传的请求头部
      type:Object,
      default: () => {
        return {}
      }
    },
    data: {//上传时额外带的参数
      type:Object,
      default: () => {
        return {}
      }
    },
    name:{//上传的文件字段名
      type: String,
      default: 'file'
    },
    cookieOK:{//支持发送 cookie 凭证信息
      type: Boolean,
      default: true
    },
    /**
     * 公共参数
     * */
    showFileList:{//是否显示已上传文件列表
      type: Boolean,
      default: false
    },
    drag:{//是否启用拖拽上传
      type: Boolean,
      default: false
    },
    accept:{//接受文件类型-图片上传类型-不同的格式之间以逗号隔开
      type: String,
      default: '.jpg,.jpeg,.png'
    },
    listType:{ // 文件列表的类型 - text/picture/picture-card
      type: String,
      default: 'picture-card'
    },
    fileList:{//已上传的文件列表,
      type:Array,
      default: () => {
        return [
          {
            name: 'food.jpeg',
            url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
          }
        ]
      }
    },
    is_disabled:{//是否禁止,true是禁止,false不禁止
      type: Boolean,
      default: false
    },
    multiple:{//是否可以多选
      type: Boolean,
      default: true
    },
 
  },
  watch: {},
  data() {
    return {
 
    }
  },
  methods: {
    /**
     * @上传文件之前的钩子
     * @params file  图片的file文件
     * @return uploadFile 把文件发送给父级
     * @tip 多选会调用多次该方法
     */
    beforeUpload(file) {
      this.$emit('uploadFile',file);
      return
    }
 
  },
 
}
</script>
 
<style lang='scss' scoped>
.uploadImgBody{
  height: auto;
  .upload-image{
    width:200px;
    height: 200px;
    .fileImg{
      width:100%;
      height: 100%;
    }
  }
  .showImg{
    width:100px;
    height: 100px;
  }
 
}
 
</style>

3、加入压缩功能

逻辑:

首先,把file文件转成  canvas图片,然后canvas压缩图片利用canvas.toDataURL()将canvas绘制的图像转成图片从而达到压缩图片尺寸的效果

HTMLCanvasElement.toDataURL()

element前端如何实现压缩图片功能

 具体方法:其中 dataUrl 就是拿到的canvas图片的base64地址

 /**
     * @压缩公共方法
     * @params file
     * @return 压缩后的文件,支持两种,file和 blob
     */
    compressImg(file) {
      const reader = new FileReader();
      // readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE,并触发 loadend (en-US) 事件,
      // 同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。
      reader.readAsDataURL(file);
      reader.onload = () => {
        const img = new Image();
        img.src = reader.result;
        img.onload = () => {
          // 图片的宽高
          const w = img.width;
          const h = img.height;
          const canvas = document.createElement("canvas");
          // canvas对图片进行裁剪,这里设置为图片的原始尺寸
          canvas.width = w;
          canvas.height = h;
          const ctx = canvas.getContext("2d");
          // canvas中,png转jpg会变黑底,所以先给canvas铺一张白底
          ctx.fillStyle = "#fff";
          // fillRect()方法绘制一个填充了内容的矩形,这个矩形的开始点(左上点)在
          // (x, y) ,它的宽度和高度分别由width 和 height 确定,填充样式由当前的fillStyle 决定。
          ctx.fillRect(0, 0, canvas.width, canvas.height);
          // 绘制图像
          ctx.drawImage(img, 0, 0, w, h);
 
          // canvas转图片达到图片压缩效果
          // 返回一个包含图片展示的 data URI base64 在指定图片格式为 image/jpeg 或 image/webp的情况下,
          // 可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
          const dataUrl = canvas.toDataURL("image/jpeg", 0.8);
          this.dialogImageUrl = dataUrl
 
        };
      };
    },

4、拿到的base64地址,不能直接给后端,要转格式,这里提供两种,一是file文件,跟压缩前的格式一样,还有一种是blob方法

// canvas生成的格式为base64,需要进行转化, base64->file
    dataURLtoFile(dataurl,fileName) {
      let 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})
    },
    // canvas生成的格式为base64,需要进行转化, base64->blob
    dataURLtoBlob(dataurl) {
      const arr = dataurl.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]);
      let n = bstr.length;
      const u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime });
    },

实现源码(上传+压缩):

uploadImg.vue

<template>
  <div class="uploadImgBody">
    <!--上传图片部分-->
    <el-upload
      class="upload-image"
      ref="upload"
      :action="action"
      :headers="headers"
      :multiple="multiple"
      :data="data"
      :name="name"
      :show-file-list="showFileList"
      :drag="drag"
      :accept="accept"
      :list-type="listType"
      :auto-upload="autoUpload"
      :disabled="is_disabled"
 
      :before-upload="beforeUpload"
    >
      <!--弹框展示上传以后的图片-->
      <img
        class="fileImg"
        v-if="mrImgUrl"
        :src="mrImgUrl"
      >
      <div v-else>
        <i class="el-icon-plus"></i>
      </div>
    </el-upload>
    源图片大小:<span v-if="sourceFile.size">{{ sourceFile.size/1024 }}</span> kb
    <el-button @click="compressImgFun" >点我压缩</el-button>
    压缩图片大小:<span v-if="compressFile.size">{{compressFile.size/1024 }}</span> kb
    <img
      v-if="dialogImageUrl"
      class="showImg"
      :src="dialogImageUrl"
    >
  </div>
 
</template>
 
<script>
//element的上传图片,压缩图片组件
export default {
  props:{
    /**
     * 自动上传参数
     * */
    autoUpload:{ // 是否需要选取完自动上传功能
      type: Boolean,
      default: true
    },
    // 默认图片,父级传过来 http开头的文件
    mrImgUrl:{
      type: String,
      default: ''
    },
    action:{//上传的地址
      type: String,
      default: ''
    },
    headers: {//设置上传的请求头部
      type:Object,
      default: () => {
        return {}
      }
    },
    data: {//上传时额外带的参数
      type:Object,
      default: () => {
        return {}
      }
    },
    name:{//上传的文件字段名
      type: String,
      default: 'file'
    },
    cookieOK:{//支持发送 cookie 凭证信息
      type: Boolean,
      default: true
    },
    /**
     * 公共参数
     * */
    showFileList:{//是否显示已上传文件列表
      type: Boolean,
      default: false
    },
    drag:{//是否启用拖拽上传
      type: Boolean,
      default: false
    },
    accept:{//接受文件类型-图片上传类型-不同的格式之间以逗号隔开
      type: String,
      default: '.jpg,.jpeg,.png'
    },
    listType:{ // 文件列表的类型 - text/picture/picture-card
      type: String,
      default: 'picture-card'
    },
    fileList:{//已上传的文件列表,
      type:Array,
      default: () => {
        return [
          {
            name: 'food.jpeg',
            url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
          }
        ]
      }
    },
    is_disabled:{//是否禁止,true是禁止,false不禁止
      type: Boolean,
      default: false
    },
    multiple:{//是否可以多选
      type: Boolean,
      default: true
    },
 
  },
  watch: {},
  data() {
    return {
      dialogImageUrl:'',//源图片
      sourceFile:{}, //上传后的图片
      compressFile:{} //压缩后的图片
 
    }
  },
  methods: {
    /**
     * @上传文件之前的钩子
     * @params file  图片的file文件
     * @return uploadFile 把文件发送给父级
     * @tip 多选会调用多次该方法
     */
    beforeUpload(file) {
      this.sourceFile = file
      this.$emit('uploadFile',file);
      return
    },
    compressImgFun(){
      this.compressImg(this.sourceFile)
      console.log('压缩前的图片文件:file');
      console.log(this.sourceFile);
    },
    /**
     * @压缩公共方法
     * @params file
     * @return 压缩后的文件,支持两种,file和 blob
     */
    compressImg(file) {
      const reader = new FileReader();
      // readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE,并触发 loadend (en-US) 事件,
      // 同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。
      reader.readAsDataURL(file);
      reader.onload = () => {
        const img = new Image();
        img.src = reader.result;
        img.onload = () => {
          // 图片的宽高
          const w = img.width;
          const h = img.height;
          const canvas = document.createElement("canvas");
          // canvas对图片进行裁剪,这里设置为图片的原始尺寸
          canvas.width = w;
          canvas.height = h;
          const ctx = canvas.getContext("2d");
          // canvas中,png转jpg会变黑底,所以先给canvas铺一张白底
          ctx.fillStyle = "#fff";
          // fillRect()方法绘制一个填充了内容的矩形,这个矩形的开始点(左上点)在
          // (x, y) ,它的宽度和高度分别由width 和 height 确定,填充样式由当前的fillStyle 决定。
          ctx.fillRect(0, 0, canvas.width, canvas.height);
          // 绘制图像
          ctx.drawImage(img, 0, 0, w, h);
 
          // canvas转图片达到图片压缩效果
          // 返回一个包含图片展示的 data URI base64 在指定图片格式为 image/jpeg 或 image/webp的情况下,
          // 可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
          const dataUrl = canvas.toDataURL("image/jpeg", 0.8);
          this.dialogImageUrl = dataUrl
 
          // base64格式文件转成Blob文件格式
          let blobFile = this.dataURLtoBlob(dataUrl);
          console.log("压缩后的图片:Blob文件----------");
          console.log(blobFile);
          // base64格式文件转成file文件格式
          let fileName = this.sourceFile.name
          let fileImg = this.dataURLtoFile(dataUrl,fileName);
          console.log("压缩后的图片:file文件----------");
          console.log(fileImg);
          this.compressFile = fileImg
 
        };
      };
    },
    // canvas生成的格式为base64,需要进行转化, base64->file
    dataURLtoFile(dataurl,fileName) {
      let 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})
    },
    // canvas生成的格式为base64,需要进行转化, base64->blob
    dataURLtoBlob(dataurl) {
      const arr = dataurl.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]);
      let n = bstr.length;
      const u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime });
    },
 
 
  },
 
}
</script>
 
<style lang='scss' scoped>
.uploadImgBody{
  height: auto;
  .upload-image{
    width:200px;
    height: 200px;
    .fileImg{
      width:100%;
      height: 100%;
    }
  }
  .showImg{
    width:100px;
    height: 100px;
  }
 
}
 
</style>

感谢各位的阅读,以上就是“element前端如何实现压缩图片功能”的内容了,经过本文的学习后,相信大家对element前端如何实现压缩图片功能这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

推荐阅读:
  1. vue2.* element tabs tab-pane如何动态加载组件
  2. element表格组件怎么使用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

element

上一篇:oracle中的case when then怎么使用

下一篇:Android拼接如何实现动态对象

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》