当前位置: 首页 > Web前端 > HTML

浏览器端使用H5实现图片压缩上传

时间:2023-04-02 22:44:09 HTML

1、需求场景:在我们的需求中,需要一个用户在手机浏览器端上传证件照的功能。我们的第一个版本是最简单的。版本,直接让用户在本地选择图片,然后上传到公司的公共服务器。功能实现后,我们发现了一个问题。公司公服有2M图片限制,目前用户手机大多支持高清拍照,尺寸一般为3000+x2000+;使用HTML5的fileReader接口对上传文件的大小进行处理,将重新处理后的压缩文件发送给后台,这样图片的基本质量得到保证(因为文档的图片,我们只关心单据编号是否清楚)。尽量减少网络传输的内容,让上传速度更快,给用户更好的体验。2、分步分析首先,我们上传的文件是输入事件默认参数中的文件类型。它是二进制大对象的一个??子集。需要将Blob类型转换成DataUrl,可以被HTML5本地Canvas画布解析,通过Canvas画布按照一定的压缩比重新压缩后,将图片转换成Blob发送到公司的公共图片服务器.selectlocalfile->Blob->DataUrl->Canvascompress->DataUrl->Blob->Uploadfile3.具体实现逻辑1,监听本地输入框的变化事件,当内容发生变化时,从中获取文件回调函数文件的参数;2、判断当前浏览器是否支持本地压缩(是否支持HTML5的fileReader方法);3、如果不支持本地压缩,使用传统方式直接将原图上传到服务器;4.如果浏览器支持本地压缩,则进入本地压缩流程;5、压缩完成后,将最新的blob类型文件传送到公司服务器;//用户选择在浏览器本地上传图片/**option={*el:element,//输入文件元素*width:800,*height:600,*rate:1,*cb:callback*}**/functioncompressUploadImageAsClient(option){varopt={el:option.el,width:option.width||800,高度:option.height||600,汇率:option.rate||1、cb:option.cb||function(){},postUrl:option.postUrl||'',postLoad:option.postLoad||function(){},postError:选项。海报罗||函数(){},postAbort:option.postAbort||功能(){}};opt.el.addEventListener('change',function(e){//如果不支持H5的filereader方法,直接使用上传原图if(typeofFileReader!='function'){//sendFile(e.target.files);postFileToServer([e.target.files[0]],opt.postUrl,opt.postLoad,opt.postError,opt.postAbort);return;}//将blob类型转换为DataUrlreadBlobAsDataURL(e.target.files[0],function(url,size){//得到url类型的图片后,通过canvasreadBase64AsBlob({url:url,size:size,width:800,height:600,rate:1,callback:function(dataUrl){//在回调函数中获取压缩后的最新图片DataUrl,转换为接口可以识别的serverBlob类型varblob=dataURLtoBlob(dataUrl);//调用服务端上传图片接口postFileToServer([blob],opt.postUrl,opt.postLoad,opt.postError,opt.postAbort);}});});},false)}//文件对象转换为dataurlfunctionreadBlobAsDataURL(blob,callback){vara=newFileReader();a.onload=function(e){回调(e.target.result,blob.size);};a.readAsDataURL(blob);}//将dataurl转换为blob函数dataURLtoBlob(dataurl){vararr=dataurl.split(','),mime=arr[0].match(/:(.*?);/)[1],bstr=atob(arr[1]),n=bstr.length,u8arr=newUint8Array(n);while(n--){u8arr[n]=bstr.charCodeAt(n);}返回新的Blob([u8arr],{type:mime});}//blob转为dataUrl,canvas压缩重新生成一个新的dataUrl/**option:{*url:图片url,*size:图片大小,*width:800,*height:600,*rate:1,*回调:回调*}*/functionreadBase64AsBlob(option){varopt={url:option.url,size:option.size,width:option.width||800,高度:option.height||600,汇率:option.rate||0.6、回调:option.callback||函数(网址){}};varimg=新图像();img.src=opt.url;img.onload=function(){varcanvas=document.createElement("canvas"),//创建一个canvas元素width=img.width,//保证canvas的大小和图片一样height=img。高度;console.log('压缩前图片的大小:',width,height);//根据最大??尺寸800x600size,按比例重新设置图片的大小varneww=opt.width;varnewh=opt.height;//当图片的宽和高分别大于800和600时,压缩它的尺寸(尺寸压缩对最终尺寸缩小效果很大)if(width>opt.width&&height>opt.height){if(高度/宽度>opt.height/opt.width){newh=opt.height;neww=(opt.height/height)*width;}else{newh=(opt.width/width)*height;neww=opt.width;}}//压缩率varrate=opt.rate;if(opt.size<1024*1024*2){//处理小于2m;rate=opt.rate*0.6;}elseif(opt.size<1024*1024*4){//在2m和4m之间rate=opt.rate*0.4;}elseif(opt.size<1024*1024*8){//在4m和8m之间rate=opt.rate*0.3;}else{//大于8m的图片rate=opt.rate*0.2;}canvas.width=neww;canvas.height=newh;canvas.getContext("2d").drawImage(img,0,0,neww,newh);//绘制图片到canvasvardataURL=canvas.toDataURL('image/jpeg',rate);//将图片转为dataURLopt.callback(dataURL);}}//通过ajax函数上传图片到公司服务器postFileToServer(files,posturl,success,fail,abort){if(!files||files.length<1){alert('上传的文件不能为空');返回;}alert('压缩图像对象:'+files[0].size);varformData=newFormData();//创建一个表单对象FormData//formData.append('submit','Submit');//向表单对象添加一个文本字段varfileNames='';对于(vari=0;i