图片裁剪+base64转file对象+前端上传OSS

本文介绍了在前端实现图片裁剪并上传到阿里云OSS的需求背景和解决方案。首先,作者遇到图片展示比例问题,通过计算图片比例解决。然后,为了提升用户体验,引入了图片裁剪组件vue-img-cutter。最后,详细阐述了如何将base64字符串转换为file对象以上传至阿里云OSS,并提供了相关资源链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

「今天实习的时候遇到了上传图片到阿里OSS的需求。过程波折,学习到了很多,遂有此篇。

需求背景:\color{skyblue}{需求背景:}需求背景:

后台页面上传图片以及简介,前台进行展示。

出现的问题:\color{skyblue}{出现的问题:}出现的问题:

后台上传原图后,前台由于布局的原因进行展示的时候总会拉伸图片或者展示不全

原图:

拉伸后的图片:

最初的解决办法:\color{skyblue}{最初的解决办法:}最初的解决办法:

上传图片后把图片隐藏,再进行图片的长宽获取,算出比例后,判断图片是否合规要求。

这里利用fixed隐藏图片

 <img :src="hiddenImgUrl" alt="" class="hiddenImg" >

.hiddenImg {position: fixed;bottom: -99999px;
} 

调用getImgWidthHeight方法算出图片的比例

 //...上传的逻辑 const imgres: any = await getImgWidthHeight(hiddenImgUrl.value)if (imgres > 0.6 && imgres < 0.9) {} else {Common.ElMessageWarning('图片宽高比例不合要求,照片宽高比例约为3:4')loading.close();return} 

异步的getImgWidthHeight方法

maxWaitLoad为超时时间

async function getImgWidthHeight(src, maxWaitLoad = 2500) {return new Promise((resolve, reject) => {let img = new Image();img.src = src;if (img.complete) {const { width, height } = img;resolve(width / height);} else {let timeOut = setTimeout(() => {reject("图片加载失败!");}, maxWaitLoad);img.onload = function () {const { width, height } = img;window.clearTimeout(timeOut);resolve(width / height);}}})
} 

这样 当用户上传的图片比例不在约束范围内的时候就会提示用户图片比例不合要求。

出现的问题:\color{skyblue}{出现的问题:}出现的问题:

这样虽然解决了图片的展示的问题,但是上传人员的体验十分不好。于是有了像裁剪头像一样图片裁剪的需求。

最终解决办法:\color{skyblue}{最终解决办法:}最终解决办法:

贴一个大佬的图片裁剪组件GitHub - acccccccb/vue-img-cutter

import ImgCutter from 'vue-img-cutter'

<ImgCutter rate="3:4" :cutWidth="300" :cutHeight="400" @cutDown="cutDown" ></ImgCutter>

const cutDown = (res) => {//res是裁剪后图片的base64的url,以及源文件名等数据easyUpload(res).then(res2 => {//调用上传oss的easyUpload方法,进行base64解码,最后进行上传ossdata.image={name: res2,url: res.fileName}//获得上传后的url,赋值给formData.photo传给后端formData.photo = data.image})
}
//...url传给后端的逻辑 

上传阿里云oss:\color{skyblue}{上传阿里云oss:}上传阿里云oss:

拿到token后获得自己阿里云的AccessKeyId,AccessKeySecret,region,bucket 文档里有写怎么获取,这里就不赘述了) 由于oss只能接收file对象、Blob数据或者OSS Buffer。所以这里还需要给base64转成file对象

这里贴一下阿里云的官方文档(简单上传 (aliyun.com))

function easyUpload(data) {return new Promise((reslove, reject) => {try {getClient().then(client => {//获取 阿里云oss的token 拿AccessKeyIdclient.put(//调用阿里云提供的方法getRandomFileName(data.file.type),//获取一个随机的文件名blobToFile(base64ToBlob(data.dataURL), data.fileName), //base64转file对象{ 'Content-Type': 'image/jpeg' }//设置Content-Type).then(res => {reslove(res.url)})})} catch (e) {reject(e)}})} 

base64转file对象:\color{skyblue}{base64转file对象:}base64转file对象:

 base64ToBlob = (base64Data) => {let arr = base64Data.split(","),fileType = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),l = bstr.length,u8Arr = new Uint8Array(l);while (l--) {u8Arr[l] = bstr.charCodeAt(l);}return new Blob([u8Arr], {type: fileType});};blobToFile = function (newBlob, fileName) {newBlob.lastModifiedDate = new Date();newBlob.name = fileName;return newBlob;} 

通过这个需求学到了很多,继续加油

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值