实现头像裁剪上传基于 vue-cropper

236 阅读3分钟

实现头像裁剪上传基于 vue-cropper

微信图片_20250424163258.jpg

本地环境好好的 发布线上之后bug就出来了

//vue-cropper 遇到的坑 Failed to execute 'getComputedStyle' on 'Window': parameter

解决办法 将 `vue-cropper` 的源码文件(如 `vue-cropper.vue``exif.main.js`)复制到该文件夹中 就不需要 vue-cropper该插件了
//仓库地址 https://github.com/aiguangyuan/vue-cropper/blob/master/src/vue-cropper.vue 

   <input
     @change="handleFileChange"
     type="file"
     accept="image/*"
     id="file"
        />
        
 <!-- 剪裁图片组件 -->
    <van-popup
      class="bg-tran"
      v-model="showCropper"
      closeable
      position="top"
      :style="{ height: '100%' }"
    >
      <div class="flex-column-center height100`">`
        <vueCropper
          ref="cropper"
          :img="option.img"
          :outputSize="option.outputSize"
          :outputType="option.outputType"
          :info="option.info"
          :full="option.full"
          :autoCropWidth="option.autoCropWidth"
          :autoCropHeight="option.autoCropHeight"
          :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"
          :high="option.high"
          :mode="option.mode"
        ></vueCropper>
        <van-col span="24">
          <van-col span="8" class="p-2"
            ><span @click="cancelCropper">取消</span></van-col
          >
          <van-col span="8"
            ><span @click="rotateImage" class="font18"
              ><van-icon name="replay"/></span
          ></van-col>
          <van-col span="8"><span @click="getCropBlob">确定</span></van-col>
        </van-col>
      </div>
    </van-popup>
    
    import vueCropper from './components/vueCropper.vue'
       option: {
        img: '',
        outputSize: 0.8,
        info: false, // 裁剪框的大小信息
        outputType: 'jpg', // 裁剪生成图片的格式
        canScale: false, // 图片是否允许滚轮缩放
        autoCrop: true, // 是否默认生成截图框
        autoCropWidth: '', // 默认生成截图框宽度
        autoCropHeight: '', // 默认生成截图框高度
        high: true, // 是否按照设备的dpr 输出等比例图片
        fixedBox: true, // 固定截图框大小 不允许改变
        fixed: true, // 是否开启截图框宽高固定比例
        fixedNumber: [1, 1], // 截图框的宽高比例
        full: true, // 是否输出原图比例的截图
        canMoveBox: false, // 截图框能否拖动
        original: false, // 上传图片按照原始比例渲染
        centerBox: false, // 截图框是否被限制在图片里面
        infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
        mode: '100% auto' // 图片默认渲染方式
      }
      
     async handleFileChange(event) {
      const file = event.target.files[0]
      event.target.value = ''; // 清除input的值,以便下次上传同一张图片
      if (file) {
        this.showCropper = true
        console.log(file.name)
        this.imageFileName = file.name
        this.imageToBase64(file)
      }
    },
    // 将本地图片转化为Base64,否则vue-cropper组件显示不出要本地需要剪裁的图片
    imageToBase64(file) {
      try {
        let reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => {
          // 截图框中的图片
          this.$nextTick(() => {
            this.option.img = reader.result // 或其他初始化操作
          })
        }
        reader.onerror = function(error) {
          console.log('Error: ', error)
          this.$toast(error)
        }
      } catch (error) {
        console.log('catch: ', error)
      }
    },
    // 确认剪裁并上传图片
    getCropBlob() {
      let formData = new FormData()
      this.$refs.cropper.getCropBlob(async data => {
        try {
          formData.append('file', data, this.imageFileName) // 通过append向form对象添加数据
         
        } catch (error) {
          console.log(error)
        }
      })
    },

image.png

文档 props参数介绍

名称 功能 默认值 可选值  
img 裁剪图片的地址 url 地址, base64, blob  
outputSize 裁剪生成图片的质量 1 0.1 ~ 1  
outputType 裁剪生成图片的格式 jpg (jpg 需要传入jpeg) jpeg, png, webp  
info 裁剪框的大小信息 true true, false  
canScale 图片是否允许滚轮缩放 true true, false  
autoCrop 是否默认生成截图框 false true, false  
autoCropWidth 默认生成截图框宽度 容器的 80% 0 ~ max  
autoCropHeight 默认生成截图框高度 容器的 80% 0 ~ max  
fixed 是否开启截图框宽高固定比例 false true, false  
fixedNumber 截图框的宽高比例, 开启fixed生效 [1, 1] [ 宽度 , 高度 ]  
full 是否输出原图比例的截图 false true, false  
fixedBox 固定截图框大小 不允许改变 false true, false
canMove 上传图片是否可以移动 true true, false  
canMoveBox 截图框能否拖动 true true, false  
original 上传图片按照原始比例渲染 false true, false  
centerBox 截图框是否被限制在图片里面 false true, false  
high 是否按照设备的dpr 输出等比例图片 true true, false  
infoTrue true 为展示真实输出图片宽高 false 展示看到的截图框宽高 false true, false  
maxImgSize 限制图片最大宽度和高度 2000 0 ~ max  
enlarge 图片根据截图框输出比例倍数 1 0 ~ max(建议不要太大不然会卡死的呢)  
mode 图片默认渲染方式 contain contain , cover, 100px, 100% auto  
limitMinSize 裁剪框限制最小区域 10 Number, Array, String  
fillColor 导出时背景颜色填充 #ffffff, white