图片裁剪 vue-cropper 的使用

6,038 阅读1分钟

官网

vue-cropper 官网

安装

# npm 安装
npm install vue-cropper

引用

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

使用

<vueCropper
  ref="cropper"
  :img="option.img"
  :outputSize="option.size"
  :outputType="option.outputType"
></vueCropper>

使用示例

vue、elementui、vue-cropper

使用 cropper 组件
<cropperDlg ref="cropperDlg" @cropperImg="cropperImg"></cropperDlg>

import cropperDlg from '@/components/cropper/cropper'
export default {
    data(){
        return {
            imgFile:''
        }
    }
    components: {
        cropperDlg
    },
    methods: {
        // 接收裁剪照片
        cropperImg(file) {
          this.imgFile = file
        },
        // 裁剪图片弹框 
        openCropper() {
          if (this.$refs.cropperDlg && this.imgFile) {
            const _f = this.imgFile
            const _file = this.dataURLtoFile(_f, 'fileCropp.png')
            // console.log(_file)
            const _fileInfo = {
                url: _f,
                size: _file.size,
                file: _file
            }
            this.$refs.cropperDlg.changeImage(_fileInfo)
          }
        },
        // 文件转base64
        readFile(file, callback) {
          var reader = new FileReader();
          reader.readAsDataURL(file);
          reader.onload = function (e) {
            callback(e.target.result)
          }
        },
        // base64转文件
        dataURLtoFile(dataurl, filename) {
          var arr = dataurl.split(',')
          var mime = arr[0].match(/:(.*?);/)[1]
          var bstr = atob(arr[1])
          var n = bstr.length
          var u8arr = new Uint8Array(n)
          while (n--) {
            u8arr[n] = bstr.charCodeAt(n)
          }
          return new File([u8arr], filename, { type: mime })
        },
    }
}
组件 cropper.vue

<template>
    <!-- vueCropper 剪裁图片实现-->
    <el-dialog title="图片剪裁" :visible.sync="dialogVisible" append-to-body>
      <div class="cropper-content">
        <div class="cropper" style="text-align:center">
          <vueCropper
            ref="cropper"
            :img="option.img"
            :output-size="option.size"
            :output-type="option.outputType"
            :info="true"
            :full="option.full"
            :can-move="option.canMove"
            :can-move-box="option.canMoveBox"
            :original="option.original"
            :auto-crop="option.autoCrop"
            :fixed="option.fixed"
            :fixed-number="option.fixedNumber"
            :center-box="option.centerBox"
            :info-true="option.infoTrue"
            :fixed-box="option.fixedBox"
          ></vueCropper>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="finish" :loading="loading">确认</el-button>
      </div>
    </el-dialog>
</template><script>
export default {
  data() {
    return {
      dialogVisible: false,
      // 裁剪组件的基础配置option
      option: {
        img: '', // 裁剪图片的地址
        info: false, // 裁剪框的大小信息
        outputSize: 1, // 裁剪生成图片的质量
        outputType: 'jpeg', // 裁剪生成图片的格式
        canScale: false, // 图片是否允许滚轮缩放
        autoCrop: true, // 是否默认生成截图框
        autoCropWidth: 360, // 默认生成截图框宽度
        autoCropHeight: 400, // 默认生成截图框高度
        fixedBox: true, // 固定截图框大小 不允许改变
        fixed: true, // 是否开启截图框宽高固定比例
        fixedNumber: [3, 4], // 截图框的宽高比例
        full: true, // 是否输出原图比例的截图
        canMoveBox: false, // 截图框能否拖动
        original: true, // 上传图片按照原始比例渲染
        centerBox: true, // 截图框是否被限制在图片里面
        infoTrue: false // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
      },
      picsList: [],  //页面显示的数组
      // 防止重复提交
      loading: false
    }
  },
  methods: {
    // 限制图片大小
    changeImage(file) {
      this.loading = false
      const isLt5M = file.size / 1024 / 1024 < 5
      if (!isLt5M) {
        this.$message.error('上传文件大小不能超过 5MB!')
        return false
      }
​
      // 上传成功后将图片地址赋值给裁剪框显示图片
      this.$nextTick(() => {
        this.option.img = file.url
        this.dialogVisible = true
      })
    },
    // 点击裁剪,这一步是可以拿到处理后的地址
    finish() {
      // const file = this.$refs.cropper.getCroppedCanvas().toDataURL()
      // console.log('fileCropper11', file)
      this.$refs.cropper.getCropBlob((data) => {
        var fileName = 'fileCropper'
        this.loading = true
        console.log(fileName, data)
        this.option.img = ''
        this.dialogVisible = false
        this.blobToDataURI(data, (res)=>{
          this.$emit('cropperImg', res)
        })
      })
    },
    // blob 装 base64
    blobToDataURI(blob, callback) {
      const reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onload = function (e) {
          callback(e.target.result);
      }
    }
  }
}
</script><style lang="scss">
// 截图
.cropper-content {
    .cropper {
        width: auto;
        height: 500px;
    }
}
</style>