Vue 图片压缩并上传至服务器功能
本文主要讲解基于Vue+Vant,实现移动端图片选择,并用Canvas压缩图片,最后上传至服务器。还会封装一个工具类,方便直接调用。
一、工具类封装
废话不多说先上代码,封装一个CompressImageUtils工具类:
** *图片压缩工具类 *最大高度和最大宽度都为500,如果超出大小将等比例缩放。 * *注意可能出现压缩后比原图更大的情况,在调用的地方自己判断大小并决定上传压缩前或压缩后的图到服务器。 */ //将base64转换为blob exportfunctionconvertBase64UrlToBlob(urlData){ letarr=urlData.split(',') letmime=arr[0].match(/:(.*?);/)[1] letbstr=atob(arr[1]) letn=bstr.length letu8arr=newUint8Array(n) while(n--){ u8arr[n]=bstr.charCodeAt(n) } returnnewBlob([u8arr],{type:mime}) } //压缩图片 exportfunctioncompressImage(path){ //最大高度 constmaxHeight=500; //最大宽度 constmaxWidth=500; returnnewPromise((resolve,reject)=>{ letimg=newImage(); img.src=path; img.onload=function(){ constoriginHeight=img.height; constoriginWidth=img.width; letcompressedWidth=img.height; letcompressedHeight=img.width; if((originWidth>maxWidth)&&(originHeight>maxHeight)){ //更宽更高, if((originHeight/originWidth)>(maxHeight/maxWidth)){ //更加严重的高窄型,确定最大高,压缩宽度 compressedHeight=maxHeight compressedWidth=maxHeight*(originWidth/originHeight) }else{ //更加严重的矮宽型,确定最大宽,压缩高度 compressedWidth=maxWidth compressedHeight=maxWidth*(originHeight/originWidth) } }elseif(originWidth>maxWidth&&originHeight<=maxHeight){ //更宽,但比较矮,以maxWidth作为基准 compressedWidth=maxWidth compressedHeight=maxWidth*(originHeight/originWidth) }elseif(originWidth<=maxWidth&&originHeight>maxHeight){ //比较窄,但很高,取maxHight为基准 compressedHeight=maxHeight compressedWidth=maxHeight*(originWidth/originHeight) }else{ //符合宽高限制,不做压缩 } //生成canvas letcanvas=document.createElement('canvas'); letcontext=canvas.getContext('2d'); canvas.height=compressedHeight; canvas.width=compressedWidth; context.clearRect(0,0,compressedWidth,compressedHeight); context.drawImage(img,0,0,compressedWidth,compressedHeight); letbase64=canvas.toDataURL('image/*',0.8); letblob=convertBase64UrlToBlob(base64); //回调函数返回blob的值。也可根据自己的需求返回base64的值 resolve(blob) } }) }
定义的最大宽度和最大高度均为500,如果图片的宽高至少有一个超出了500,都会被**等比例**压缩,不用担心变形。可以根据自己项目需要改变maxWidth和 maxHeight。
这里直接把压缩的最大高度和最大宽度写死为500了,没有在调用时传。因为一个项目压缩的逻辑和大小一般都一致的,没必要在每次调用的时候传。当然如果想写的灵活一点,可以在compressImage方法里再把maxWidth、maxHeight和压缩质量传上。
compressImage方法返回的是blob值,根据服务端接口需要可以改为返回base64,只需将resolve(blob)改为resolve(base64)即可。
注意一点,对于有些宽高没到500,且分辨率很小的图片,压缩之后可能比之前还大。猜测可能是canvas生成的图片分辨率要比原来高一些,所以最终的图片比压缩前更大。可以在调用的地方加个判断,如果压缩完的大小比原图小,就上传压缩后的图片;如果如果压缩完的大小比原图大,就上传原图。
二、如何使用
将CompressImageUtils引入到目标文件,然后调用 compressImage方法,即可在回调里获得压缩后的结果。注意 compressImage方法返回的是Promise。
省略其他无关代码,只保留跟压缩图片和上传相关的:
在返回结果中加了层判断,压缩后比原来更大,则将原图上传;压缩后比原来小,上传压缩后的。解决压缩后比原图更大的情况。
this.$api.uploadImage(params)是调用封装的api方法,如下:
//上传图片 uploadImage(params){ returnaxios.post(`${base}/api/v1/file`,params,{ headers:{'content-type':'multipart/form-data'} }) },
三、使用效果
先上传一个非常大的,尺寸为6016×4016,16.8M的大图,看输出日志,压缩后大小仅为260k左右。此时判断压缩后比压缩前小,上传压缩图到服务器。
再看个尺寸300×300,12k的小图,压缩前大小是11252,压缩后大小是93656,大了很多。此时判断压缩后比压缩前更大,上传的是原图。
总结:这个工具类对大图的压缩效果很明显,不管多大的图,压缩之后基本不会超过300k。但对某些小图可能出现压缩完反而更大的情况。在调用的地方加层压缩后和压缩前大小的比较判断,会完美解决这个问题。
当然也可以在工具类内部判断,但个人觉得跟业务逻辑相关的代码还是不要放在公用的工具类比较好。
总结
以上所述是小编给大家介绍的Vue图片压缩并上传至服务器功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。