《vue-element实现图片上传裁剪功能》

效果图

 

 

 

 

 

1.安装插件

npm install vue-cropper // npm 安装
yarn add vue-cropper // yarn 安装

2.引用

// 全局引用 main.js
import VueCropper from 'vue-cropper'
Vue.use(VueCropper)

// 局部引用
import VueCropper from 'vue-cropper'
components: {
   VueCropper
 },

 

3. vue界面中

3-1.上传按钮和裁剪完成后的图片预览

<el-form-item label="产品图片:" label-width="100px">
          <el-upload
            class="avatar-uploader"
            accept=".png,.jpeg,.jpg,.JPG,.JPEG,"
            action=""
            :auto-upload="false"
            :show-file-list="false"
            :on-change='handleChangeUpload'>
            <el-button size="small" type="primary">选择图片</el-button>
          </el-upload>
  </el-form-item>
<el-form-item label="图片预览:" class="box" label-width="100px">
        <div class="crop-img-box">
            <img v-else :src="form.imgFile" />
        </div>
 </el-form-item>

3-2.设置一个弹出层,放剪裁图片的cropper

<el-dialog title="图片剪裁" :visible.sync="imgdialogVisible" class="crop-dialog" append-to-body>
        <div class="cropper-content">
            <div class="cropper" style="text-align:center">
                <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"
                    :fixed="option.fixed"
                    :fixedNumber="option.fixedNumber"
                    :centerBox="option.centerBox"
                    :infoTrue="option.infoTrue"
                    :fixedBox="option.fixedBox"
                    :autoCropWidth="option.autoCropWidth"
                    :autoCropHeight="option.autoCropHeight"
                    @realTime="getCropImg"
                />
            </div>
        </div>
        <div class="action-box">
            <el-upload class="upload-demo"
              style="margin-right:8px"
              action=""
              :auto-upload="false"
              :show-file-list="false"
              :on-change='handleChangeUpload'>
              <el-button type="primary" plain>更换图片</el-button>
            </el-upload>
            <el-button style="margin-right:8px" type="primary" icon="el-icon-delete" plain @click="clearImgHandle">清除图片</el-button>
            <el-button-group>
              <el-button type="primary" icon="el-icon-refresh-left" plain @click="rotateLeftHandle">左旋转</el-button>
              <el-button type="primary" icon="el-icon-refresh-right" plain @click="rotateRightHandle">右旋转</el-button>
              <el-button type="primary" icon="el-icon-zoom-in" plain @click="changeScaleHandle(1)">放大</el-button>
              <el-button type="primary" icon="el-icon-zoom-out" plain @click="changeScaleHandle(-1)">缩小</el-button>
            </el-button-group>
        </div>
        <div slot="footer" class="dialog-footer">
            <el-button @click="imgdialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="finish" :loading="loading">完成截取</el-button>
        </div>
  </el-dialog>

3-3.裁剪框的样式

.cropper-content {
    .cropper {
        width: auto;
        height: 350px;
    }
  }
 

4.js方法

 注:option是剪裁插件的属性配置,具体更多含义查看官网介绍

<script>
export default {
  data() {
    return {
 
      form:{
        imgFile:"",
      },
 
      isPreview: false,
      imgdialogVisible: false,
      previewImg: '', // 预览图片地址
      // 裁剪组件的基础配置option
      option: {
          img: 'https://pic1.zhimg.com/80/v2-366c0aeae2b4050fa2fcbfc09c74aad4_720w.jpg', // 裁剪图片的地址
          info: true, // 裁剪框的大小信息
          outputSize: 1, // 裁剪生成图片的质量
          outputType: 'png', // 裁剪生成图片的格式
          // outputType:'blob',
          canScale: true, // 图片是否允许滚轮缩放
          autoCrop: true, // 是否默认生成截图框
          canMoveBox: true, // 截图框能否拖动
          autoCropWidth: 400, // 默认生成截图框宽度
          autoCropHeight: 300, // 默认生成截图框高度
          fixedBox: false, // 固定截图框大小 不允许改变
          fixed: false, // 是否开启截图框宽高固定比例
          fixedNumber: [3,2], // 截图框的宽高比例
          full: false, // 是否输出原图比例的截图
          original: false, // 上传图片按照原始比例渲染
          centerBox: false, // 截图框是否被限制在图片里面
          infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
      },
      // 防止重复提交
      loading: false,
    };
  },
  methods: {
    // 上传按钮 限制图片大小和类型
    handleChangeUpload(file) {
        this.$nextTick(async () => {
            // base64方式
            // this.option.img = await fileByBase64(file.raw)
            this.option.img = URL.createObjectURL(file.raw)
            this.loading = false
            this.imgdialogVisible = true;
        })
    },
    //更换图片
    changeScaleHandle(num) {
        num = num || 1;
        this.$refs.cropper.changeScale(num);
    },
   //左右旋转
    rotateLeftHandle() {
        this.$refs.cropper.rotateLeft();
    },
    rotateRightHandle() {
        this.$refs.cropper.rotateRight();
    },
    //清除图片
    clearImgHandle() {
      this.option.img = '';
      this.form.imgFile= "";
    },
    //这里是点击确定之后预览图片
    getCropImg () {
      if (this.option.outputType === "blob") {
        this.$refs.cropper.getCropBlob(data => {
          // var img = window.URL.createObjectURL(data);
          var img = data;
          this.form.imgFile = img;
        });
      } else {
        this.$refs.cropper.getCropData(data => {
          this.form.imgFile = data;
          this.form.imgFile = this.base64ToFile(data, 'docpic.jpg')
        });
      }
    },
   //完成裁剪时的确定按钮,
    finish() {
        // 获取截图的 blob 数据
        this.$refs.cropper.getCropBlob((blob) => {
            this.loading = true
            this.imgdialogVisible = false
            this.previewImg = URL.createObjectURL(blob)
            this.isPreview = true
            // console.log("获取blob:",this.previewImg)
        })
        // 获取截图的 base64 数据
        this.$refs.cropper.getCropData(data => {
          //  console.log("获取 base64 数据:", data)
        })
    },
   //将base64格式转换为文件格式,因为我这向后台提交数据时需要文件格式
    base64ToFile(urlData, fileName) {
      let arr = urlData.split(',');
      let mime = arr[0].match(/:(.*?);/)[1];
      let bytes = atob(arr[1]); // 解码base64
      let n = bytes.length
      let ia = new Uint8Array(n);
      while (n--) {
          ia[n] = bytes.charCodeAt(n);
      }
      return new File([ia], fileName, { type: mime });
    },
  },
};
</script>

 

posted @ 2021-12-17 10:13  爱听书的程序猿  阅读(732)  评论(0编辑  收藏  举报