vue-cropper 裁剪圖片

先展示一下效果

如何使用:

1、安裝 

npm install vue-cropper    (如果安裝不上,用cnpm)

2、直接貼代碼爽快人就是這樣

<template>
  <el-dialog
    title="裁剪圖片"
    :visible.sync="visible"
    @close="onCallback(false)"
    class="handleDialog"
    width="1000px"
  >
    <div class="wrap">
      <div class="main">
        <div class="cropperContent">
          <div class="cropper">
            <vueCropper
              ref="cropper"
              :img="option.img"
              :outputSize="option.size"
              :outputType="option.outputType"
              :info="true"
              :full="option.full"
              :canMove="option.canMove"
              :canMoveBox="option.canMoveBox"
              :original="option.original"
              :autoCrop="option.autoCrop"
              :autoCropWidth="option.autoCropWidth"
              :autoCropHeight="option.autoCropHeight"
              :fixedBox="option.fixedBox"
              @realTime="realTime"
              @imgLoad="imgLoad"
            ></vueCropper>
          </div>
          <div class="previewBox">
            <div class="title">實時預覽</div>
            <div
              class="showPreview"
              :style="{
                width: previews.w + 'px',
                height: previews.h + 'px',
              }"
            >
              <div :style="previews.div" class="preview">
                <img :src="previews.url" :style="previews.img" />
              </div>
            </div>
          </div>
        </div>

        <div class="footerButton">
          <div class="scopeButton">
            <label class="localButton" for="uploads">本地圖片</label>
            <input
              type="file"
              id="uploads"
              class="inputFile"
              accept="image/png, image/jpeg, image/gif, image/jpg"
              @change="uploadImg($event)"
            />

            <el-button
              type="primary"
              @click="changeScale(1)"
              icon="el-icon-plus"
            ></el-button>
            <el-button
              type="primary"
              @click="changeScale(-1)"
              icon="el-icon-minus"
            ></el-button>
            <el-button
              type="primary"
              @click="rotateLeft"
              icon="el-icon-refresh-left"
            ></el-button>
            <el-button
              type="primary"
              @click="rotateRight"
              icon="el-icon-refresh-right"
            ></el-button>
          </div>
          <div class="uploadButton">
            <el-button
              @click="down('blob')"
              type="primary"
              icon="el-icon-download"
              >下載</el-button
            >
            <el-button
              @click="uploadNewPic"
              type="primary"
              icon="el-icon-upload2"
              >上傳</el-button
            >
          </div>
        </div>
      </div>
      <div class="end">
        <el-button type="primary" @click="saveNewPic">保存</el-button>
        <el-button @click="onCallback(false)">取消</el-button>
      </div>
    </div>
  </el-dialog>
</template>
<script>
import { VueCropper } from "vue-cropper";
import { imgView, imgUploadUrl, uploadImg } from "services";
import { alerts } from "js/yydjs.js";
export default {
  components: { VueCropper },
  data() {
    return {
      imgView,
      picId: "",
      newPicId: "",
      crap: false,
      previews: {},
      option: {
        img: "",
        size: 1,
        full: false, //輸出原圖比例截圖 props名full
        outputType: "png",
        canMove: true,
        original: false,
        canMoveBox: false,
        autoCrop: true,
        autoCropWidth: 300,
        autoCropHeight: 300,
        fixedBox: true,
      },
      downImg: "#",
      cate: "",
      ratio: 1,
    };
  },
  mounted() {
    this.option.img = this.imgView + this.picId;
    this.option.autoCropHeight = this.option.autoCropWidth * this.ratio;
  },
  methods: {
    saveNewPic() {
      if (!this.newPicId) {
        return alerts("請上傳裁剪後的圖片");
      }
      this.onCallback(this.newPicId);
    },
    changeScale(num) {
      num = num || 1;
      this.$refs.cropper.changeScale(num);
    },
    rotateLeft() {
      this.$refs.cropper.rotateLeft();
    },
    rotateRight() {
      this.$refs.cropper.rotateRight();
    },
    // 實時預覽函數
    realTime(data) {
      console.log(data, "realTime");
      this.previews = data;
    },
    // 將base64轉換爲文件 百度隨便找的 看需求使用
    dataURLtoFile(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 });
    },
    uploadNewPic() {
      this.$refs.cropper.getCropData((data) => {
        let name = new Date().getTime();
        let file = this.dataURLtoFile(data, `${name}.png`);
        console.log(file, "ssss");
        let fd = new FormData();
        fd.append("file", file);
        fd.append("cate", this.cate);
        uploadImg(fd).then((res) => {
          if (res) {
            let { scaleRelativePath = "" } = res.body;
            this.newPicId = scaleRelativePath;
            alerts("上傳成功", "success"); // 自己寫的彈框
          }
        });
      });
    },
    down(type) {
      // event.preventDefault()
      var aLink = document.createElement("a");
      aLink.download = "author-img";
      // 輸出
      if (type === "blob") {
        this.$refs.cropper.getCropBlob((data) => {
          console.log(data, type);
          this.downImg = window.URL.createObjectURL(data);
          // aLink.download = this.downImg;
          console.log(this.downImg);
          aLink.href = window.URL.createObjectURL(data);
          aLink.click();
        });
      } else {
        this.$refs.cropper.getCropData((data) => {
          this.downImg = data;
          aLink.href = data;
          aLink.click();
        });
      }
    },
    uploadImg(e) {
      //上傳圖片
      // this.option.img
      var file = e.target.files[0];
      if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
        alerts("圖片類型必須是.gif,jpeg,jpg,png,bmp中的一種");
        return false;
      }
      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;
      };
      // 轉化爲base64
      // reader.readAsDataURL(file)
      // 轉化爲blob
      reader.readAsArrayBuffer(file);
    },
    imgLoad(msg) {
      console.log(msg, "msg");
    },
  },
};
</script>
<style lang="scss" scoped>
@import "~css/public.scss";
.handleDialog {
  @include cententCenterDialog;
  .cropperContent {
    display: flex;
    justify-content: space-between;
    padding-left: 20px;
    .cropper {
      width: 400px;
      height: 400px;
      border: 1px solid #ddd;
    }
    .previewBox {
      flex: 1;
      display: flex;
      justify-content: center;
      flex-direction: column;
      align-items: center;
      .title {
        font-size: 18px;
        height: 36px;
        margin-bottom: 20px;
      }
      .showPreview {
        flex: 1;
        display: flex;
        justify-content: center;
        .preview {
          overflow: hidden;
          background: #eeeeee;
          border: 1px solid #eeeeee;
        }
      }
    }
  }
  .footerButton {
    margin-top: 30px;
    margin-left: 20px;
    display: flex;
    justify-content: flex-end;
    .scopeButton {
      width: 400px;
      display: flex;
      justify-content: space-between;
    }
    .uploadButton {
      flex: 1;
      display: flex;
      justify-content: center;
    }
    .localButton {
      cursor: pointer;
      color: #ffffff;
      background: #409eff;
      padding: 10px 15px;
      border-radius: 3px;
      appearance: none;
      display: flex;
      align-self: center;
      margin-right: 10px;
    }
    .inputFile {
      width: 180px;
      position: absolute;
      clip: rect(0 0 0 0);
    }
  }
}
</style>

3、說明,支持網絡圖片也支持本地圖片,圖片如果需要上傳,我是通過base64轉文件,再上傳的,喜歡的請給我點個贊,評論都可以

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章