web技术分享| 图片上传与图片裁剪结合 vue3
需求:
-
上传的图片限制长宽相同; 只能上传图片; 图片大小限制 500k 当前项目仅需要上传的图片信息
项目组件使用
裁剪:vue-cropper
import "vue-cropper/dist/index.css";
import {
VueCropper } from "vue-cropper";
上传: Upload 上传(element plus 组件)
实现理论:
- 通过组件 Upload 进行图片上传前校验方法判断是否需要裁剪、是否是图片、是否超过大小限制;
- 裁剪后的图片限制大小;
- 上传的图片信息暴漏出组件;
组件调用
img-url 默认预览的图片 @img-upload 上传所需的最终图片
代码实现
页面
裁剪时弹窗显示
<!-- 上传 -->
<el-upload
class="uploader_cutsom"
action=""
:show-file-list="false"
:accept="imgUpload.imgBmp"
:http-request="updataImg"
:before-upload="beforUpload"
>
<div v-if="imgUpload.imageUrl" class="w-full h-full relative">
<img class="w-full h-full" :src="imgUpload.imageUrl" />
<!-- 删除 -->
<div
@click="clearImg"
class="absolute top-0 right-0 w-8 h-8 rounded flex items-center justify-center bg-black bg-opacity-30 text-white text-base z-20 cursor-pointer"
>
<i class="iconfont icon-shanchu"></i>
</div>
</div>
<div v-else class="uploader_cutsom_default">
<p>从你的计算机中</p>
<p class="uploader_cutsom_default_button">选择文件</p>
</div>
</el-upload>
<!-- 裁剪 -->
<el-dialog
v-model="imgUpload.dialogCropping"
custom-class="dialog_custom"
title="裁剪图片"
append-to-body
:close-on-press-escape="false"
:show-close="false"
:close-on-click-modal="false"
>
<div>
<div class="h-96 w-full">
<vueCropper
ref="cropper"
class="vue_cropper_custom"
:img="imgCropping.imageUrl"
:outputType="imgCropping.outputType"
:autoCrop="imgCropping.autoCrop"
:autoCropWidth="imgCropping.autoCropWidth"
:autoCropHeight="imgCropping.autoCropHeight"
:fixed="imgCropping.fixed"
:fixedNumber="imgCropping.fixedNumber"
:centerBox="imgCropping.centerBox"
:full="imgCropping.full"
></vueCropper>
</div>
</div>
<template #footer>
<el-button v-focus @click="handleCropping($refs.cropper, false)">
取消
</el-button>
<el-button
v-focus
type="primary"
@click="handleCropping($refs.cropper, true)"
>
确定
</el-button>
</template>
</el-dialog>
逻辑
图片相关方法封装
/** 查询图片大小 */
export const imgSize = (file: any) => {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
// 让页面中的img标签的src指向读取的路径
let img = new Image();
img.src = reader.result as string;
if (img.complete) {
// 如果存在浏览器缓存中
if (img.width / img.height !== 1) {
resolve(false);
} else {
resolve(true);
}
} else {
img.onload = () => {
if (img.width / img.height !== 1) {
resolve(false);
} else {
resolve(true);
}
};
}
};
});
};
/**
* 文件格式转换
* @description blobToFile
* @param {Blob} blob
* @param {String} fileName
*/
export const blobToFile = (blob: any, fileName: string) => {
return new window.File([blob], fileName, {
type: blob.type,
});
};
