Corte a imagem, corte de acordo com a proporção, passo a passo
1: el-upload seleciona imagens locais (duas etapas de seleção local e upload)
2: Obtenha a imagem selecionada por el-upload no método de retorno de chamada on-change e exiba-a no vueCropper ().
2.1: Antes de exibir o vueCropper, use a caixa de marcadores el-dialog para exibir.
3: Enviar: obtenha a imagem recortada no método de retorno de chamada realTime do vueCropper, converta-a em base64 e, em seguida, converta-a em um arquivo de arquivo e envie-a ao servidor.
Veja as etapas do código
一: upload elétrico
el-upload link: Upload | Element Plus
Resumidamente, esta é uma função de selecionar imagens locais para upload. As duas funções de "selecionar imagens locais" e "servidor de upload" podem ser implementadas juntas ou separadamente. Como preciso delas aqui, elas são implementadas separadamente.
O componente de função de seleção e upload do elementplus é escolhido aqui, é claro, você também pode escrevê-lo.
<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; // 控制显示弹框
})
},
Dois: obtenha a imagem e exiba-a na caixa pop-up (aqui estão as etapas)
Obtenha o img do método onchange de el-upload. Deixe a caixa pop-up el-dialog exibir vuecropper.
Site oficial: https://github.com/xyxiao001/vue-cropper
e carregar
<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.length
let 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;
})
}
}