vueCropper设置最大宽高的坑

1,161 阅读1分钟

vueCropper踩过的坑,公司业务需求是按照指定尺寸裁剪,原本想着截出来在用canvas放大,后面发现有enlarge这个属性,

一开始想着设置5比较好计算,后面有一个尺寸是需要2788高,发现只有2692高,看了相关文档还是不行,找了一遍设置maxImgSize: 3000,也还是不行,最发现enlarge这个属性设置6就可以,由此可见enlarge也会限制宽高

image.png

配置的相关代码 image.png

const options: Options = reactive({
  img: "", // 需要剪裁的图片
  autoCrop: true, // 是否默认生成截图框
  autoCropWidth: 150, // 默认生成截图框的宽度
  autoCropHeight: 150, // 默认生成截图框的长度
  fixedBox: true, // 是否固定截图框的大小 不允许改变
  info: true, // 裁剪框的大小信息
  outputSize: 1, // 裁剪生成图片的质量 [10.1]
  outputType: "png", // 裁剪生成图片的格式
  canScale: false, // 图片是否允许滚轮缩放
  fixed: false, // 是否开启截图框宽高固定比例
  fixedNumber: [1, 1], // 截图框的宽高比例 需要配合centerBox一起使用才能生效
  full: true, // 是否输出原图比例的截图
  canMoveBox: false, // 截图框能否拖动
  original: false, // 上传图片按照原始比例渲染
  centerBox: true, // 截图框是否被限制在图片里面
  infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
  enlarge: 6, //图片根据截图框输出比例倍数
  maxImgSize: 3000,
});

封装的组件代码

<template>
  <div @click="uploadClick">
    <input type="file" accept="image/*" @change="onChange" id="fileBtn" style="display: none" />
    <div v-if="!isPic">
      <slot></slot>
    </div>
    <div v-else>
      <img v-if="src" :src="$isOnlinePic(src)" alt="" class="addUpload">
      <div v-else class="addUpload flex-ct">+</div>
    </div>
  </div>
  <el-dialog v-model="dialogVisible" title="Picture cropping" width="50%" :before-close="
      () => {
        dialogVisible = false;
      }
    ">
    <div style="width: 100%; height: 50vh">
      <vueCropper ref="cropperRef" :img="options.img" :info="true" :infoTrue="options.infoTrue" :auto-crop="options.autoCrop" :fixed-box="options.fixedBox" :fixedNumber="fixedNumber" :fixed="options.fixed" :autoCropWidth='width'
        :autoCropHeight='height' :centerBox="options.centerBox" @realTime="realTime" :outputType="'png'" :enlarge="options.enlarge" :maxImgSize="options.maxImgSize">
      </vueCropper>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">Cancel</el-button>
        <el-button type="" @click="refreshCrop">Reset</el-button>
        <el-button type="primary" @click="finish"> Confirm </el-button>
      </span>
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
import VueCropper from "vue-cropper/src/vue-cropper.vue";
import { initCOS } from "@/utils/upload";

const props = withDefaults(
  defineProps<{
    width: number;
    height: number;
    src: string;
    isPic: boolean;
    isFullPath: boolean;
    fixedNumber: number[];
  }>(),
  {
    isPic: true,
    isFullPath: true,
    fixedNumber: () => [1, 1],
  }
);
interface Options {
  img: string | ArrayBuffer | null; // 裁剪图片的地址
  info: true; // 裁剪框的大小信息
  outputSize: number; // 裁剪生成图片的质量 [1至0.1]
  outputType: "png"; // 裁剪生成图片的格式
  canScale: boolean; // 图片是否允许滚轮缩放
  autoCrop: boolean; // 是否默认生成截图框
  autoCropWidth: number; // 默认生成截图框宽度
  autoCropHeight: number; // 默认生成截图框高度
  fixedBox: boolean; // 固定截图框大小 不允许改变
  fixed: boolean; // 是否开启截图框宽高固定比例
  fixedNumber: Array<number>; // 截图框的宽高比例  需要配合centerBox一起使用才能生效
  full: boolean; // 是否输出原图比例的截图
  canMoveBox: boolean; // 截图框能否拖动
  original: boolean; // 上传图片按照原始比例渲染
  centerBox: boolean; // 截图框是否被限制在图片里面
  infoTrue: boolean; // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
}

const options: Options = reactive({
  img: "", // 需要剪裁的图片
  autoCrop: true, // 是否默认生成截图框
  autoCropWidth: 150, // 默认生成截图框的宽度
  autoCropHeight: 150, // 默认生成截图框的长度
  fixedBox: true, // 是否固定截图框的大小 不允许改变
  info: true, // 裁剪框的大小信息
  outputSize: 1, // 裁剪生成图片的质量 [1至0.1]
  outputType: "png", // 裁剪生成图片的格式
  canScale: false, // 图片是否允许滚轮缩放
  fixed: false, // 是否开启截图框宽高固定比例
  fixedNumber: [1, 1], // 截图框的宽高比例 需要配合centerBox一起使用才能生效
  full: true, // 是否输出原图比例的截图
  canMoveBox: false, // 截图框能否拖动
  original: false, // 上传图片按照原始比例渲染
  centerBox: true, // 截图框是否被限制在图片里面
  infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
  enlarge: 6, //图片根据截图框输出比例倍数
  maxImgSize: 3000,
});
const previews: any = ref({});
let fileItem = reactive({});
const cropperRef: any = ref({});
const dialogVisible = ref(false);
// 触发点击事件
const uploadClick = () => {
  document.getElementById("fileBtn")?.click();
};
const onChange = (e: any) => {
  const file = e.target.files[0];
  fileItem = file;
  console.log("file:", file);
  const URL = window.URL || window.webkitURL;
  options.img = URL.createObjectURL(file);
  console.log("options.img:", options.img);
  dialogVisible.value = true;
};
const refreshCrop = () => {
  cropperRef.value.refresh();
};
const emits = defineEmits([]);
// 上传图片(点击保存按钮)
const finish = () => {
  cropperRef.value.getCropBlob(async (data: any) => {
    console.log("获取截图的 blob 数据:", data);
    // 下面是将blob转为formData
    let formData = new FormData();
    formData.append("file", data, new Date().getTime() + ".png");
    // 下面是将blob转换为file
    data.lastModifiedDate = new Date(); // 文件最后的修改日期
    let file = new File([data], fileItem?.name, {
      type: data.type,
      lastModified: Date.now(),
    });
  });

  dialogVisible.value = false;
};
// 裁剪之后的数据
const realTime = (data: any) => {
  previews.value = data;
};
</script>
<style lang="scss" scoped>
.addUpload {
  width: 60px;
  height: 60px;
  border: 1px solid #e5e5e5;
  border-radius: 10px;
}
// :deep(.crop-info){
//   display: none;
// }
</style>

组件使用

//这里可以定义接收方法,将其上传到服务器
<Cropper width='170.6' height='170.6'>
 <span class="btnColor" @click="click">Upload</span>
</Cropper>