裁切图片,按照比例裁切,分步骤
1:el-upload选择本地图片(分选择本地和上传两步骤)
2:在on-change回调方法中拿到el-upload选中的图片,显示在vueCropper上()。
2.1:在vueCropper显示前,用el-dialog弹框显示。
3:提交:拿到vueCropper的回调方法realTime中的裁切好的图片,转化为base64,再转为file文件提交上传给服务器。
看代码步骤
一:el-upload
el-upload连接:Upload | Element Plus
简单介绍,这个是一个选择本地图片上传的功能,这“选择本地图片”“上传服务器”两个功能可以一起实现,也可以分开实现,因我这里需要,是分开实现。
这里选择的是elementplus的选取上传功能组件,当然也可以自己去写。
<el-upload accept="image/jpeg, image/gif, image/png, image/jpg" ref='upload' :action="uploadAction" //上传方法,:auto-upload="false" //是否自动上传文件。这里需要false:headers="uploadHeaders" :limit="1" :show-file-list="false" //上传显示的列表:on-change="onChange" //选择文件或上传文件成功或上传文件失败时的钩子功能><el-button type="default">选择图片</el-button></el-upload>
// 选择本地图片onChange(file, fileList) {this.$nextTick(() => {this.option.img = URL.createObjectURL(file.raw);this.$refs.upload.clearFiles();this.dialogVisibleImgs = true; // 控制显示弹框})},
二:拿到图片,弹框显示(这里分步骤)
从el-upload的onchange方法中拿到img。让el-dialog弹框显示vuecropper。并上传
<el-dialog class="cropperDialog" :close-on-click-modal="false" title="图片裁剪" :visible.sync="dialogVisibleImgs"width="40%" @close="close"><div class="cropper-content" v-if="option.img"><div class="cropper" style="text-align: center;"><vueCropper ref="cropper" :img="option.img" :output-size="option.size" :output-type="option.outputType":info="true" :full="option.full" :fixed="option.fixed" :fixed-number="option.fixedNumber":can-move="option.canMove" :can-move-box="option.canMoveBox" :fixed-box="option.fixedBox":original="option.original" //上传图片按照原始比例渲染 原图裁切大小的需写这个:auto-crop="option.autoCrop" :auto-crop-width="option.autoCropWidth" // 默认生成裁图框宽度 原图裁切大小的需写这个" :auto-crop-height="option.autoCropHeight" // 默认生成裁图框高度 原图裁切大小的需写这个:center-box="option.centerBox" :high="option.high"model="cover" :max-img-size="option.max" :info-true="option.infoTrue" @realTime="realTime" //实时预览函数></vueCropper></div></div><div class="dialogbottom" style="display: flex; align-items: center; justify-content: space-between;"><div class="preview"><!-- 这里传入封装的裁切比例 --><div class="title">封面预览 图片比例({{ fixedNum[0] }}:{{fixedNum[1]}})</div><div class="preview_clumk"><img :src="previewImageHeight" alt="" style="width:90px;"object-fit="contain"></div></div><div><el-button style="margin-left: 10px; margin-top: 20px; " type="success" :loading="loading"@click="uploadEnd">上传并保存</el-button></div></div></el-dialog>
// // 实时预览函数realTime(data) {// ①获取截图的 base64 数据this.$refs.cropper.getCropData((data) => {this.previewImageHeight = data;})},//将base64转换为file文件流base64toFile(dataurl, filename = 'file') {let arr = dataurl.split(',')let mime = arr[0].match(/:(.*?);/)[1]let suffix = mime.split('/')[1]let bstr = atob(arr[1])let n = bstr.lengthlet u8arr = new Uint8Array(n)while (n--) {u8arr[n] = bstr.charCodeAt(n)}return new File([u8arr], `${filename}.${suffix}`, {type: mime,})},// 自定义上传给后台,这里能最大限度自定义uploadEnd() {if (!this.option.img && this.option.img == '')return this.ME('请先选择图片')this.loading = true;if (this.previewImageHeight !== '') {const optionImg = this.base64toFile(this.previewImageHeight);const formData = new FormData()formData.append('file', optionImg);this.$api.Media.Image.Upload(formData).then((res) => {this.loading = false;this.imageUrl = res.data.url;this.$message.success('上传成功');this.$emit("input", this.imageUrl);this.close();}).catch(() => {this.loading = false;})}}
.sync:https://www.cnblogs.com/weiziyu/p/12012498.html