cropperjs上传图片截取

cropperjs上传图片截取

参考:https://www.jianshu.com/p/9dc2f643cb6a
参考:https://www.jianshu.com/p/4fc756df20f9

  • 首先下载依赖npm i cropperjs,这里上传用到了ali-oss,所以同时安装ali-oss的依赖npm i ali-oss
  • 组件代码如下
<template>
  <div class="v-simple-cropper">
    <!-- <input class="file" type="file" accept="image/*" @change="uploadChange" /> -->
    <van-uploader
      v-model="fileList"
      :after-read="afterRead"
      :before-delete="beforeDelete"
      :max-count="1"
      image-fit="contain"
    />
    <div class="tip">请上传一寸免冠照片</div>
    <div class="v-cropper-layer" ref="layer" v-show="showlayer">
      <div class="layer-header">
        <button class="cancel" @click="cancelHandle">取消</button>
        <button class="cancel" @click="cropperRotate(90)">旋转</button>
        <button class="confirm" @click="confirmHandle">选取</button>
      </div>
      <img ref="cropperImg" />
    </div>
  </div>
</template>

<script>
import Cropper from "cropperjs";
import "cropperjs/dist/cropper.min.css";
import { getALiYun } from "@/api/dict";
import { client } from "@/utils/alioss";
export default {
  name: "Cropper",
  props: {
    fileUrl: String,
    uploadURL: Function,
    deleteURL: Function,
  },
  data() {
    return {
      cropper: null,
      showlayer: false,
      initParam: {
        scale: 1, // 相对手机屏幕放大的倍数
      },
      fileList: [],
      ALiYun: {},
    };
  },
  created() {
    this.getALiYun();
  },
  mounted() {
    this.init();
    if (this.fileUrl) {
      const index = this.fileUrl.lastIndexOf("/");
      const name = this.fileUrl.substr(index + 1);
      let obj = {
        content: this.fileUrl,
        url: this.fileUrl,
        name: decodeURIComponent(name),
      };
      this.fileList.push(obj);
    }
  },
  methods: {
    // 获取后台OSS数据源
    async getALiYun() {
      getALiYun().then((res) => {
        if (res.code === 200) {
          this.ALiYun = res.data;
        }
      });
    },
    // 初始化
    init() {
      const cropperImg = this.$refs.cropperImg;
      this.cropper = new Cropper(cropperImg, {
        aspectRatio: 446 / 650, // 剪裁比例
        dragMode: "move",
        viewMode: 1,
        cropBoxResizable: false,
      });
    },
    // 选择图片
    afterRead(file) {
      // 判断扩展名
      const tmpCnt = file.file.name.lastIndexOf(".");
      const exName = file.file.name.substring(tmpCnt + 1);
      const names = ["jpg", "jpeg", "png"];
      if (names.indexOf(exName) < 0) {
        this.fileList = [];
        this.$Toast.fail("不支持的格式!");
        return;
      }
      this.fileList[0].status = "uploading";
      this.fileList[0].message = "上传中..";
      const URL = window.URL || window.webkitURL;
      let binaryData = [];
      binaryData.push(file.file);
      this.cropper.replace(URL.createObjectURL(new Blob(binaryData)));
      this.showlayer = true;
    },
    // 旋转
    cropperRotate(val) {
      this.cropper.rotate(val);
    },
    cancelHandle() {
      this.cropper.reset();
      this.fileList = [];
      this.showlayer = false;
    },
    confirmHandle() {
      const cropBox = this.cropper.getCropBoxData();
      const scale = this.initParam["scale"] || 1;
      this.cropper
        .getCroppedCanvas({
          width: cropBox.width * scale,
          height: cropBox.height * scale,
        })
        //把裁剪的图片转换成blob类型文件,在通过new File(),转换成file文件
        .toBlob(async (blob) => {
          //重置file的name,以时间戳作为文件名
          const timeString = new Date().getTime();
          const imgFile = new File([blob], `${timeString}.jpg`, {
            type: "image/jepg",
          });
          this.showlayer = false;
          const res = await this.uploadFile(imgFile);
          this.$emit("uploadURL", res);
        });
    },
    uploadFile(file) {
      return new Promise((resolve) => {
        const fileName = `${Date.parse(new Date())}/${file.name}`; //定义唯一的文件名
        return client(this.ALiYun)
          .put(fileName, file)
          .then(({ res, url, name }) => {
            if (res && res.status == 200) {
              console.log("阿里云OSS上传成功");
              let obj = {
                name: file.name,
                content: url,
                file,
              };
              this.fileList = [];
              this.fileList.push(obj);
              resolve(url);
            } else {
              this.fileList = [];
              this.$Toast.fail("上传失败");
            }
          })
          .catch((err) => {
            console.log(`阿里云OSS上传失败回调`, err);
          });
      });
    },
    beforeDelete(){
      this.fileList = [];
      this.$emit("deleteURL");
    }
  },
};
</script>
<style lang="less" scoped>
.v-simple-cropper {
  // width: 100%;
  // height: 100%;
  // position: absolute;
  // left: 0;
  // top: 0;
  text-align: center;
  padding-top: 10px;
  // .file {
  //   // width: 100%;
  //   // height: 100%;
  //   // opacity: 0;
  //   // width: 100px;
  //   height: 100px;
  // }
  .tip {
    font-size: 14px;
    margin: 5px 0;
  }

  /deep/.van-uploader__upload {
    margin: 0 !important;
  }
  .v-cropper-layer {
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: #fff;
    z-index: 99999;
    .layer-header {
      position: absolute;
      bottom: 0;
      left: 0;
      z-index: 99999;
      background: rgba(#fff, 0.5);
      width: 100%;
      height: 1.5rem;
      padding: 0 0.2rem;
      box-sizing: border-box;
      display: flex;
      justify-content: space-between;
    }
    .cancel,
    .confirm {
      line-height: 1.5rem;
      font-size: 0.58rem;
      background: none;
      border: 0;
      outline: 0;
      // float: left;
    }
    // .confirm {
    //   // float: right;
    // }
    img {
      position: inherit !important;
      border-radius: inherit !important;
      float: inherit !important;
    }
  }
}
</style>
  • 页面引入及使用代码如下
<Cropper
  @uploadURL="uploadURL"
  @deleteURL="deleteURL"
  :fileUrl="infoForm.personalPhoto"
 />

import Cropper from "@/components/Cropper/index.vue";
components: {
    Cropper,
  },
// 获取图片url
    uploadURL(url) {
      console.log(url, "1111111111111111");
    },
    deleteURL() {
      this.infoForm.personalPhoto = "";
    },
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容