vue项目,使用vue-cropper进行图片的截图裁剪并上传

1.  安装依赖

npm install vue-cropper

2.  引入  可以单页面引入  也可以全局引入

单页面

import VueCropper from 'vue-cropper'

全局 - 在main.js里

import VueCropper from 'vue-cropper'
Vue.use(VueCropper)

3.  HTML页面

          <vueCropper
            ref="cropper"
            :img="option.img"
            :outputSize="option.size"
            :outputType="option.outputType"
            :info="option.info"
            :full="option.full"
            :canMove="option.canMove"
            :canMoveBox="option.canMoveBox"
            :original="option.original"
            :autoCrop="option.autoCrop"
            :autoCropWidth="option.autoCropWidth"
            :autoCropHeight="option.autoCropHeight"
            :fixedBox="option.fixedBox"
          ></vueCropper>

4.  data

      option: {
        img: "", // 裁剪图片的地址
        info: true, // 裁剪框的大小信息
        outputSize: 0.8, // 裁剪生成图片的质量
        outputType: "jpeg", // 裁剪生成图片的格式
        canScale: false, // 图片是否允许滚轮缩放
        autoCrop: true, // 是否默认生成截图框
        autoCropWidth: 200, // 默认生成截图框宽度
        autoCropHeight: 100, // 默认生成截图框高度
        fixedBox: false, // 固定截图框大小 不允许改变
        fixed: true, // 是否开启截图框宽高固定比例
        fixedNumber: [7, 5], // 截图框的宽高比例
        full: true, // 是否输出原图比例的截图
        canMoveBox: true, // 截图框能否拖动
        original: true, // 上传图片按照原始比例渲染
        centerBox: false, // 截图框是否被限制在图片里面
        infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
      },

methods


    handleConfirm() {
      this.$refs.cropper.getCropBlob((data) => {
        // if (data.size > 2097152) {
        //   this.showMsg("图片大于2M,请进行裁剪或重新选择");
        // }
        let blob = window.URL.createObjectURL(data);
        this.downImg = blob;
        var base64;
        var img = new Image();
        img.src = blob;
        var _that = this;
        img.onload = function () {
          var that = this;
          //生成比例
          var w = that.width,
            h = that.height,
            scale = w / h;
          h = w / scale;
          //生成canvas
          var canvas = document.createElement("canvas");
          var ctx = canvas.getContext("2d");
          canvas.width = w;
          canvas.height = h;
          ctx.drawImage(that, 0, 0, w, h);
          // 生成base64
          _that.cropperPic = canvas.toDataURL("image/jpeg", 0.8);
          let files = _that.transformToFiles(_that.cropperPic, _that.filename);
          _that.temporaryCloseCropper = true;

          // XMLHttpRequest 请求 --最后决定使用 XMLHttpRequest 来进行上传图片
          var xhr = new XMLHttpRequest();
          xhr.timeout = 3000;
          xhr.ontimeout = function (event) {
            console.log("请求超时!");
          };
          let param = new FormData();
          param.append("file", files, _that.filename);
          param.append("deadline", 0); // 按照接口需求情况添加
          param.append("file_size", 512 * 1024); // 按照接口需求情况添加
          xhr.open(
            "POST",
            "https://xxxxxxxxxxxx"
          );
          xhr.send(param);
          xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
              console.log(JSON.parse(xhr.responseText));
              let data = JSON.parse(xhr.responseText);
              _that.imageUrl = data.url;
              console.log(_that.imageUrl);
              _that.dialogVisible = false;
            } else {
              console.log(xhr.statusText);
            }
          };

          // 生成图片
          // _that.$refs.upload.$children[0].handleChange({
          //   target: { files: [files] },
          // });

          //  未解决 调用上传 但是无法获取返回信息(可能有我什么不知道的方法可以获取接口返回)
          // _that.$refs.upload.$children[0].post(files)
        };
      });
    },

全部代码

<template>
  <div>
    <el-upload
      class="avatar-uploader"
      action="https://xxxxxxxxxxxx"
      :show-file-list="false"
      :before-upload="beforeAvatarUpload"
      :data="{ deadline: 0, file_size: 512 * 1024 }"
      :model="imageUrl"
      ref="upload"
      accept="image/*"
      :limit="1"
    >
      <img v-if="imageUrl" :src="imageUrl" class="avatar" />
      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>

    <el-dialog
      title="封面裁剪"
      ref="dialog"
      width="40%"
      :visible.sync="dialogVisible"
      :close-on-click-modal="false"
    >
      <div class="cropper-w">
        <div class="cropper" :style="{ width: '100%', height: '280px' }">
          <vueCropper
            ref="cropper"
            :img="option.img"
            :outputSize="option.size"
            :outputType="option.outputType"
            :info="option.info"
            :full="option.full"
            :canMove="option.canMove"
            :canMoveBox="option.canMoveBox"
            :original="option.original"
            :autoCrop="option.autoCrop"
            :autoCropWidth="option.autoCropWidth"
            :autoCropHeight="option.autoCropHeight"
            :fixedBox="option.fixedBox"
          ></vueCropper>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="handleConfirm">确认</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dialogVisible: false,
      imageUrl: "",
      option: {
        img: "", // 裁剪图片的地址
        info: true, // 裁剪框的大小信息
        outputSize: 0.8, // 裁剪生成图片的质量
        outputType: "jpeg", // 裁剪生成图片的格式
        canScale: false, // 图片是否允许滚轮缩放
        autoCrop: true, // 是否默认生成截图框
        autoCropWidth: 200, // 默认生成截图框宽度
        autoCropHeight: 100, // 默认生成截图框高度
        fixedBox: false, // 固定截图框大小 不允许改变
        fixed: true, // 是否开启截图框宽高固定比例
        fixedNumber: [7, 5], // 截图框的宽高比例
        full: true, // 是否输出原图比例的截图
        canMoveBox: true, // 截图框能否拖动
        original: true, // 上传图片按照原始比例渲染
        centerBox: false, // 截图框是否被限制在图片里面
        infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
      },
    };
  },
  methods: {
    beforeAvatarUpload(file) {
      this.filename = file.name;
      this.openCropper(file);
      return false;
    },
    openCropper(file) {
      var _this = this;
      console.log(_this);
      const isJPG =
        file.type === "image/jpeg" ||
        file.type === "image/jpg" ||
        file.type === "image/png" ||
        file.type === "image/PNG" ||
        file.type === "image/JPG";
      if (!isJPG) {
        this.$message.error("上传图片只能为jpg或png格式");
        return;
      }
      var reader = new FileReader();
      reader.onload = (e) => {
        let data;
        if (typeof e.target.result === "object") {
          // 把Array Buffer转化为blob 如果是base64不需要
          data = window.URL.createObjectURL(new Blob([e.target.result]));
        } else {
          data = e.target.result;
        }
        _this.option.img = data;
        _this.dialogVisible = true;
      };
      // 转化为base64
      reader.readAsDataURL(file);
      // 转化为blob
      // reader.readAsArrayBuffer(file);
    },
    handleConfirm() {
      this.$refs.cropper.getCropBlob((data) => {
        // if (data.size > 2097152) {
        //   this.showMsg("图片大于2M,请进行裁剪或重新选择");
        // }
        let blob = window.URL.createObjectURL(data);
        this.downImg = blob;
        var base64;
        var img = new Image();
        img.src = blob;
        var _that = this;
        img.onload = function () {
          var that = this;
          //生成比例
          var w = that.width,
            h = that.height,
            scale = w / h;
          h = w / scale;
          //生成canvas
          var canvas = document.createElement("canvas");
          var ctx = canvas.getContext("2d");
          canvas.width = w;
          canvas.height = h;
          ctx.drawImage(that, 0, 0, w, h);
          // 生成base64
          _that.cropperPic = canvas.toDataURL("image/jpeg", 0.8);
          let files = _that.transformToFiles(_that.cropperPic, _that.filename);
          _that.temporaryCloseCropper = true;

          // XMLHttpRequest 请求 --最后决定使用 XMLHttpRequest 来进行上传图片
          var xhr = new XMLHttpRequest();
          xhr.timeout = 3000;
          xhr.ontimeout = function (event) {
            console.log("请求超时!");
          };
          let param = new FormData();
          param.append("file", files, _that.filename);
          param.append("deadline", 0); // 按照接口需求情况添加
          param.append("file_size", 512 * 1024); // 按照接口需求情况添加
          xhr.open(
            "POST",
            "https://xxxxxxxxxxxx"
          );
          xhr.send(param);
          xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
              console.log(JSON.parse(xhr.responseText));
              let data = JSON.parse(xhr.responseText);
              _that.imageUrl = data.url;
              console.log(_that.imageUrl);
              _that.dialogVisible = false;
            } else {
              console.log(xhr.statusText);
            }
          };

          // 生成图片
          // _that.$refs.upload.$children[0].handleChange({
          //   target: { files: [files] },
          // });

          //  使用此方法 需要在 upload 里 action 设置接口地址
          // _that.$refs.upload.$children[0].post(files)
        };
      });
    },

    // base64转成files
    transformToFiles(dataurl, filename) {
      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 });
    },
  },
};
</script>

<style lang='scss'>
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值