vueCropper踩过的坑,公司业务需求是按照指定尺寸裁剪,原本想着截出来在用canvas放大,后面发现有enlarge这个属性,
一开始想着设置5比较好计算,后面有一个尺寸是需要2788高,发现只有2692高,看了相关文档还是不行,找了一遍设置maxImgSize: 3000,也还是不行,最发现enlarge这个属性设置6就可以,由此可见enlarge也会限制宽高
配置的相关代码
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,
});
封装的组件代码
<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>