素材巴巴 > 程序开发 >

web技术分享| 图片上传与图片裁剪结合 vue3

程序开发 2023-09-07 06:05:25

需求:

项目组件使用

裁剪:vue-cropper

import "vue-cropper/dist/index.css";
 import { VueCropper } from "vue-cropper";
 

上传: Upload 上传(element plus 组件)

实现理论:

  1. 通过组件 Upload 进行图片上传前校验方法判断是否需要裁剪、是否是图片、是否超过大小限制;
  2. 裁剪后的图片限制大小;
  3. 上传的图片信息暴漏出组件;

组件调用

img-url 默认预览的图片
@img-upload 上传所需的最终图片

代码实现

页面

裁剪时弹窗显示

从你的计算机中

选择文件

逻辑

/** 图片地址传递 */
 const prop = defineProps({imgUrl: {type: String,default: "",},
 });
 /** 事件通知 */
 const emit = defineEmits(["img-upload"]);/** 图片上传 */
 const imgUpload = reactive({// 是否展示裁剪dialogCropping: false,isCropping: false, // 判断是否已经截图// 图片imageUrl: "",// 图片格式imgBmp: "image/*",// 图片名称imgName: "",
 });
 // 图片上传前校验
 const beforUpload: UploadProps["beforeUpload"] = async (rawFile) => {// 判断是否需要进行裁剪imgUpload.isCropping = (await imgSize(rawFile)) as boolean;// 图片名称imgUpload.imgName = rawFile.name;if (imgUpload.isCropping) {if (rawFile.type.indexOf("image/") === -1) {ElMessage.error("请上传正确的图片格式");return false;} else if (rawFile.size / 1024 / 1024 > 0.5) {ElMessage.error("图片大小不能超过 500k");return false;}} else {// 进入裁剪imgCropping.imageUrl = URL.createObjectURL(rawFile);imgUpload.dialogCropping = true;return false;}
 };
 // 上传
 const updataImg = async (data: any) => {// 如果未截图,打开裁剪if (imgUpload.isCropping) {// 图片预览imgUpload.imageUrl = URL.createObjectURL(data.file);imgUpload.dialogCropping = false;imgUpload.isCropping = false;// 图片信息emit("img-upload", data.file);}
 };/** 图片裁剪 */
 const imgCropping = reactive({imageUrl: "",// 裁剪生成图片的格式outputType: "png",// 是否默认生成截图框autoCrop: true,// 上传图片按照原始比例渲染//   original: true,// 是否输出原图比例的截图full: false,// 默认生成截图框宽度autoCropWidth: 160,// 默认生成截图框高度autoCropHeight: 160,// 是否开启截图框宽高固定比例fixed: true,// 截图框的宽高比例fixedNumber: [1, 1],// 截图框是否被限制在图片里面centerBox: true,
 });// 生成裁剪图片
 const handleCropping = (roleRefs: any, type: boolean) => {if (type) {roleRefs.getCropBlob((data: any) => {// 判断裁剪图片大小if (data.size / 1024 / 1024 > 0.5) {ElMessage.error("裁剪图片大小不能超过 500k");} else {// 图片预览imgUpload.imageUrl = URL.createObjectURL(data);imgUpload.dialogCropping = false; // 图片信息emit("img-upload", blobToFile(data, imgUpload.imgName));}});} else {imgUpload.imageUrl = "";imgUpload.dialogCropping = false;}
 };// 清除图片
 const clearImg = () => {imgUpload.imageUrl = "";emit("img-upload");
 };onMounted(() => {// 图片地址传递imgUpload.imageUrl = prop.imgUrl;
 });
 

图片相关方法封装

/** 查询图片大小 */
 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,});
 };
 

在这里插入图片描述


标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。