首页 > 其他分享 >vue-cropper插件使用

vue-cropper插件使用

时间:2022-12-29 13:11:58浏览次数:57  
标签:插件 vue 上传 截图 var file cropper true 图片

<template>
  <el-form-item :label="label" prop="coverUrl">
    <el-image
      v-if="ruleCoverUrl"
      class="uploadImgwh"
      :src="ruleCoverUrl"
      @click="clickImgUpdata"
    />
    <div v-else class="updataCourseImage uploadImgwh">
      <el-button @click="clickImgUpdata">上传封面图片</el-button>
    </div>
    <!-- 上传课程封面弹框 -->
    <el-dialog
      title="上传课程封面"
      v-loading="loading"
      :element-loading-text="'正在上传中...' + per + '%'"
      :close-on-press-escape="false"
      :close-on-click-modal="false"
      append-to-body
      :visible.sync="dialogImg"
      width="50%"
    >
      <div class="updataimg">
        <div>
          <div class="cropper-content" v-if="coverUrl">
            <div class="cropper" style="text-align:center">
              <vueCropper
                ref="cropper"
                :img="option.img"
                :outputSize="option.outputSize"
                :outputType="option.outputType"
                :info="option.info"
                :canScale="option.canScale"
                :autoCrop="option.autoCrop"
                :autoCropWidth="option.autoCropWidth"
                :autoCropHeight="option.autoCropHeight"
                :fixedBox="option.fixedBox"
                :fixed="option.fixed"
                :fixedNumber="option.fixedNumber"
                :canMove="option.canMove"
                :canMoveBox="option.canMoveBox"
                :original="option.original"
                :centerBox="option.centerBox"
                :infoTrue="option.infoTrue"
                :full="option.full"
                :enlarge="option.enlarge"
                :mode="option.mode"
                @realTime='realTime'
              >
              </vueCropper>
            </div>
          </div>
          <div
            v-else
            class="updataCourseImage uploadImgwh"
          >
            <span>暂无封面图片</span>
          </div>
        </div>
        <div>
          <div style="width: 222px;height: 138px; padding: 0 0 30px 30px;">
            <img :src='previewImg'  alt="请上传后再预览" class='previewImg' style="display: inline-block; width: 192px; height: 108px;  border: 1px dashed #87cefa;">
          </div>
          <div class="updataimg_right">
            <h3>封面预览</h3>
            <p>注意:</p>
            <p>封面不允许涉及政治色彩和色情;</p>
            <p>支持jpg/gif/png格式,2M以内;</p>
            <p>建议最佳封面尺寸比例:16 : 9</p>
            <el-button
              size="mini"
              type="primary"
              @click="uploadFile"
              style="margin-right: 30px"
            >上传</el-button
            >
            <input
              v-show="false"
              ref="fileRef"
              accept=".png, .jpg, .jpeg, .webp, .gif"
              type="file"
              @change="beforeAvatarUpload($event)"
            />
            <el-button size="mini" @click="clearImg">清空</el-button>
          </div>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="clearBtn">取 消</el-button>
        <el-button type="primary" @click="addCoverUrl">保 存</el-button>
      </span>
    </el-dialog>
  </el-form-item>
</template>
<script>
import { _api_stsTokenUpdata } from "@/api/oss/oss.js";

import { VueCropper } from 'vue-cropper'
export default {
  components: { VueCropper },
  props: {
    ruleCoverUrl: String,
    label: String,
  },
  data() {
    return {
      // loading
      loading: false,
      // 弹出框
      dialogImg: false,
      // 弹出框内图
      coverUrl: undefined,
      // 进度
      per: 0,
      // 上传点
      abortCheckpoint: undefined,
      option: {
        img: 'https://cmp-uploadfile.oss-cn-beijing.aliyuncs.com/52785f074330e.jpg', // 裁剪图片的地址 url 地址, base64, blob, 给个默认,防止报错
        outputSize: 0.5, // 裁剪生成图片的质量
        outputType: 'png', // 裁剪生成图片的格式 jpeg, png, webp
        info: true, // 裁剪框的大小信息
        canScale: true, // 图片是否允许滚轮缩放
        autoCrop: true, // 是否默认生成截图框
        autoCropWidth: 256, // 默认生成截图框宽度
        autoCropHeight: 144, // 默认生成截图框高度
        fixedBox: false, // 固定截图框大小 不允许改变
        fixed: true, // 是否开启截图框宽高固定比例
        fixedNumber: [16, 9], // 截图框的宽高比例 [ 宽度 , 高度 ]
        canMove: true, // 上传图片是否可以移动
        canMoveBox: true, // 截图框能否拖动
        original: false, // 上传图片按照原始比例渲染
        centerBox: true, // 截图框是否被限制在图片里面
        infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
        full: false, // 是否输出原图比例的截图
        enlarge: '2', // 图片根据截图框输出比例倍数
        mode: 'contain' // 图片默认渲染方式 contain , cover, 100px, 100% auto
      },
      success: () => {}, // 回调方法
      previewImg: null, // 预览后的图片
      resImg:null,
    }
  },
  methods: {
    //获取图片预览
    realTime (data) {
      const that = this
      this.$refs.cropper.getCropBlob(data => {
        console.log(data)
        // 这里data数据为Blob类型,blobToDataURI方法转换成base64
        this.blobToDataURI(data, function(res) {
          that.previewImg = res
        })
      })
    },
    // 课程封面的点击事件
    clickImgUpdata() {
      this.dialogImg = true;
      this.coverUrl = this.ruleCoverUrl;
    },
    // 上传代理
    uploadFile() {
      this.$refs.fileRef.dispatchEvent(new MouseEvent("click"));
    },
    // base64转化为Blob/file对象
    convertBase64ToBlob(imageEditorBase64) {
      var base64Arr = imageEditorBase64.split(",");
      var imgtype = "";
      var base64String = "";
      if (base64Arr.length > 1) {
        //如果是图片base64,去掉头信息
        base64String = base64Arr[1];
        imgtype = base64Arr[0].substring(
          base64Arr[0].indexOf(":") + 1,
          base64Arr[0].indexOf(";")
        );
      }
      // 将base64解码
      var bytes = atob(base64String);
      //var bytes = base64;
      var bytesCode = new ArrayBuffer(bytes.length);
      // 转换为类型化数组
      var byteArray = new Uint8Array(bytesCode);

      // 将base64转换为ascii码
      for (var i = 0; i < bytes.length; i++) {
        byteArray[i] = bytes.charCodeAt(i);
      }

      // 生成Blob对象(文件对象)

      let blob =  new Blob([bytesCode], { type: imgtype });
      let filename = new Date().getTime() + '';
      //生成file文件对象
      var file = new File([blob], filename, {type: imgtype, lastModified: Date.now()});
      return file

    },
    // 图片上传保存
    addCoverUrl() {
      console.log(this.previewImg)
      if(!this.previewImg){
        return this.$message.warning('未上传文件,请上传文件后再进行保存!')
      }
      let file = this.convertBase64ToBlob(this.previewImg)
      this.OSS(file)
    },
    // 清空图片列表
    clearImg() {
      this.coverUrl = "";
      this.previewImg = ''
    },
    // 关闭上传图片弹框
    clearBtn() {
      this.clearImg();
      this.dialogImg = false;
    },
    // 上传
    async beforeAvatarUpload(e) {
      // 获取到第一张图片
      const file = e.target.files[0];
      let regImage = ["image/jpg", "image/jpeg", "image/png", "image/gif"];
      if (regImage.indexOf(file.type) == -1) {
        this.$message.error("请上传图片!!!");
        return;
      }
      const isLt2M = file.size / 1024 / 1024 < 2;
      if (!isLt2M) {
        this.$message.error("上传的封面图片大小不能超过 2MB!");
        return;
      }
      const aBlob = new Blob(e.target.files)
      let that = this
      this.blobToDataURI(aBlob, function(res) {
        that.coverUrl = res
        that.option.img = res
      })
    },
    blobToDataURI(blob, callback) {
      var reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onload = function (e) {
        callback(e.target.result);
      }
    },
    async OSS(file){
      this.loading = true;
      const filename = file.name;

      // 获取STS token
      let credentials = await _api_stsTokenUpdata();

      // 创建对象
      this.ossClient = new OSS({
        region: "oss-cn-beijing",
        accessKeyId: credentials.data.accessKeyId,
        accessKeySecret: credentials.data.accessKeySecret,
        stsToken: credentials.data.securityToken,
        bucket: credentials.data.bucketName,
        secure: true,
      });

      this.ossClient
        .multipartUpload(filename, file, {
          parallel: 1,
          partSize: 1024 * 1024,
          progress: (p, cpt, res) => {
            // 获取上传进度。
            this.abortCheckpoint = cpt;
            console.log(p * 100);
            this.per = Math.floor(p * 100);
          },
        })
        .then((result) => {
          console.log(result)
          let index = result.res.requestUrls[0].lastIndexOf("?")
          if(index == -1){
            this.coverUrl = result.res.requestUrls[0]
            // this.option.img = this.coverUrl
          }else{
            this.coverUrl = result.res.requestUrls[0].substr(0,index)
            // this.option.img = this.coverUrl
          }
          this.$emit("giveruleCoverUrl", this.coverUrl)
          // e.target.value = ''
          this.dialogImg = false
          this.loading = false;
        })
        .catch(function (err) {
          console.log(err);
          this.loading = false;
        });
    },
  },
};
</script>
<style lang="scss" scoped>
.updataimg {
  display: flex;
  .updataimg_right {
    padding: 30px;
    h3 {
      font-weight: bolder;
      font-size: 16px;
    }
    p {
      margin: 0;
      font-size: 12px;
    }
  }
}
// 上传课程封面
.updataCourseImage {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px dashed #87cefa;
  background-color: #fcfdfd;
}
.uploadImgwh{
  width: 512px;
  height: 288px;
}
.real_info_class {
  .el-checkbox__input .el-checkbox__inner {
    border-radius: 0;
  }
}
.file-image {
  width: 320px;
  height: 320px;
  font-size: 14px;
  border: 1px solid #cccccc;
  margin: 15px 0;
}

/* 截图 */
/* .cropper-content {} */
.cropper {
  width: 512px;
  height: 288px;
}
</style>

标签:插件,vue,上传,截图,var,file,cropper,true,图片
From: https://www.cnblogs.com/gyh907368/p/17012265.html

相关文章

  • VueJS使用addEventListener的事件如何触发执行函数的this
    1、使用浏览器监听切屏为例此处为考虑浏览器兼容性推荐使用:document.addEventListener1.1、正常函数使用如下:letn=0;letmax=3;//切屏最大次数document.addE......
  • (一)Vue 3 项目搭建
    确保已安装16.0或更高版本的Node.js,然后在命令行中运行以下命令:npminitvue@latest这一指令将会安装并执行create-vue,它是Vue官方的项目脚手架工具。你将会看到......
  • vue基本语法
    vue基本语法v-bind<!DOCTYPEhtml><htmllang="en"xmlns:v-bind="http://www.w3.org/1999/xhtml"><head><metacharset="UTF-8"><title>Title</title>......
  • vue入门
    Vue入门SOC:关注度分离原则网页三要素:HTML+CSS+js:视图:给用户看,刷新后台给的数据网络通信:axios页面跳转:Vue-router状态管理:vuexVue-UI:ICEM模型V视图C控制器......
  • 【前端vue开发架构】vue开发单页项目架构总结
    活动设计的前端架构主要的技术栈为Vuejs,Webpack,请自行阅读如下技术或者框架的文档:一、基础说明:node (https://nodejs.org/en/)npm(​​https://www.npmjs.com​​)webpac......
  • 推荐几个好用的GDB图形化功能增强插件
    GDB插件汇总插件介绍GEF扩充GDB功能的python脚本Pwndbg强大的GDB功能扩展插件,工具众多gdb-dashboard增强gdb功能界面gdbguigdb浏览器前端调试界面......
  • 仿京东产品图放大镜效果优化版与jQZoom v2.0插件实现放大镜效果
    放大镜放大镜顾名思义就是放大某一样东西,显示更多的细节给用户查看。左边是小图,右边是大图;当鼠标放在小图上时,右边的大图会显示对应的细节。代码来自于黑马程序员视频教程......
  • 【MindStudio训练营第一季】OpenCV插件-案例复现​
    【MindStudio训练营第一季】OpenCV插件-案例复现​案例复现流程​OpenCV插件介绍​本代码仓插件实现了opencv的抠图和缩放功能。抠图:支持根据目标检测的(x,y)坐标和(width,heig......
  • Vue2下的路由的基本使用
    路由理解:一个路由(route)就是一组映射关系(key-value),多个路由需要路由器(router)进行管理。前端路由:key是路径,value是组件。1.基本使用安装vue-router,命令:npmivue-......
  • vue3+vite build打包报错:Some chunks are larger than 500 KiB after minification. C
    看官方的解决方案:1、在rollup配置文件中添加output.manualChunks,将模块拆分成多个chunk,减小每个chunk的大小;2、build.chunkSizeWarningLimit,提高报错的阈值;3、使用动......