这个问题被测试妹子反馈了好几次,也解决了好多次。虽然用了比较死板的方法,但总算是解决了。因为php同事说页面上的图片要通过七牛的接口直接上传到七牛,所以后端无法处理,前端必须处理2m以下的图片。不过感觉之前的方法只是减少了宽高,并不能保证压缩后一定会小于2m。所以没办法,还是得去做。/***将图像转换为base64*/functionimgBase64(file){varself=this;//检查是否支持FileReaderif(!file||!window.FileReader)return;//创建一个图像对象varimage=newImage();//绑定加载事件处理器,加载完成后执行image.onload=function(){//获取画布DOM对象varcanvas=document.createElement('canvas')//返回一个对象,用于在画布上绘制的环境,'2d'指定要在画布上绘制的类型varctx=canvas.getContext('2d')//如果高度超过标准//参数,最大高度varMAX_HEIGHT=9000;if(image.height>MAX_HEIGHT){//宽度按比例缩放*=image.width*=MAX_HEIGHT/image.height;image.height=MAX_HEIGHT;}//获取canvas的2d环境对象,//可以理解为Context是管理员,canvas是房子//canvas清屏console.log('canvas.width:',canvas.width);ctx.clearRect(0,0,canvas.width,canvas.height);//重置画布宽度和高度canvas.width=image.width;canvas.height=image.height;//将图像绘制到画布上ctx.draw图片(图片,0,0,图片宽度,图片高度);//!!!请注意,图像不会添加到domconsole.log(file.type);//console.log(canvas.toDataURL('image/jpeg',0.5));//------------//varmaxSize=2*1024;//2MvarfileSize=file.size/1024;//图片大小if(fileSize>maxSize){//如果图片大于2m,压缩console.log(maxSize,fileSize,maxSize/fileSize);uploadSrc=canvas.toDataURL(file.type,maxSize/fileSize);document.getElementById('previewImage').src=uploadSrc;uploadFile=convertBase64UrlToFile(uploadSrc,file.name.split('.')[0]);//转换为文件}else{uploadSrc=canvas.toDataURL(file.type,0.5);文档。getElementById('previewImage').src=uploadSrc;上传文件=文件;}//------------//};if(/^image/.test(file.type)){//创建一个阅读器varreader=newFileReader();//将图片转成base64格式重新ader.readAsDataURL(文件);//读取成功后的回调reader.onload=function(){//设置src属性,浏览器会自动加载//记住事件一定要先绑定才能设置src属性,否则会有同步问题。image.src=this.result;}}}这段代码就是找之前别人写的代码,然后加点东西凑合一下。之前没怎么压缩过图片,感觉宽和高不能压缩得太小,怕图片压缩模糊,所以傻傻的把最大高度设置成9000。varMAX_HEIGHT=9000;压缩图像质量也设置为一个奇怪的值。uploadSrc=canvas.toDataURL(file.type,maxSize/fileSize);上网测试了一波,原来是哪里出了问题。测试同学反馈用户问题:压缩后大于2m!所以我改变了很多想法。varmaxSize=1.5*1024;//1.5M的结果又出问题了:小于2m的图片压缩后会大于2m!我突然想到了一个问题。大于1.5m的图片转base64后,可能大于2m。我只是盲目地改变了它。于是又想着改一下最大高度,试试看。顺便降低画质。varMAX_HEIGHT=4000;...uploadSrc=canvas.toDataURL(file.type,0.3);//将0.5更改为0.3。试完之后,女孩心虚地问,没事吧?心里也很空虚,干脆加了个判断。如果压缩后还是大于2m,我会提示你重新上传图片。当时都是在线的,不过测试了几天,妹子想了想,提示还是不友好不合理,又开始催优化。我改变了计划。如果压缩后大于2m,我再压缩一遍。我认为这应该是万无一失的。果然测试了很久,用户也没有反映。至少经过了比较长的实践检验。其实最大高度改了一点点到3000,但是感觉没什么用。/***验证转换后的图片大小并上传*/functioncheckAndHandleUpload(file){imgBase64(file,function(image,canvas){varmaxSize=2*1024;//2MvarfileSize=file.size/1024;//图片大小if(fileSize>maxSize){//如果图片大于2m,压缩console.log(maxSize,fileSize,maxSize/fileSize);uploadSrc=canvas.toDataURL(file.type,maxSize/fileSize);uploadFile=convertBase64UrlToFile(uploadSrc,file.name.split('.')[0]);//转换为文件}else{uploadSrc=image.src;//canvas.toDataURL(file.type,0.5);uploadFile=file;}varcompressedSize=uploadFile.size/1024/1024;if(compressedSize.toFixed(2)>2.00){checkAndHandleUpload(uploadFile);}else{document.getElementById('previewImage').src=uploadSrc;}});}/***将图像转换为base64*/functionimgBase64(file,callback){varself=this;//检查是否支持FileReaderif(!file||!window.FileReader)返回;//创建一个图像对象varimage=newImage();//绑定load事件处理器,执行image.onload=function(){//获取画布DOM对象varcanvas=document.createElement('canvas')//返回画布上绘制的上下文,'2d'指定你想在画布上绘制的类型varctx=canvas.getContext('2d')//如果超出高度//参数,最大高度varMAX_HEIGHT=3000;if(image.height>MAX_HEIGHT){//按比例缩放宽度*=image.width*=MAX_HEIGHT/image.height;image.height=MAX_HEIGHT;}//获取canvas的2D环境对象,//可以理解为Context是管理员,canvas是房子//Canvas清屏console.log('canvas.width:',canvas.width);ctx.clearRect(0,0,canvas.width,canvas.height);//重置画布的宽度和高度canvas.width=image.width;canvas.height=image.height;//在画布上绘制图像ctx.drawImage(image,0,0,image.width,image.height);//!!!请注意,图像未添加到domconsole.log(file.t类型);//console.log(canvas.toDataURL('image/jpeg',0.5));//------------//回调(图像,画布);//--------//};if(/^image/.test(file.type)){//创建一个阅读器varreader=newFileReader();//将图片转换成base64格式reader.readAsDataURL(file);//读取成功回调reader.onload=function(){//self.imgUrls.push(this.result);//设置src属性,浏览器会自动加载//记得绑定第一个事件,src属性可以设置,否则会出现同步问题。image.src=this.result;}}}
