内容简介:图片的上传一般情况下不需要上传大体积的图片,因为如果是用户头像或者是一些要求清晰度不是太高的场景上传大体积图片会很消耗资源,一个是上传耗时比较长,同时也增加了存储的开销,当展示的时候也会消耗下载的带宽,影响加载效率。要求用户上传的图片之前压缩图片很影响用户体验,所以就增加了在前端进行图片压缩的需求。前端图片压缩的主要思路就是将图片绘制到canvas中,然后通过canvas的toDataURL方法来控制图片的质量,对图片进行压缩,另一方面是对图片进行宽高等比缩小来达到图片压缩的效果,下面来看一下代码示例:在上
图片的上传一般情况下不需要上传大体积的图片,因为如果是用户头像或者是一些要求清晰度不是太高的场景上传大体积图片会很消耗资源,一个是上传耗时比较长,同时也增加了存储的开销,当展示的时候也会消耗下载的带宽,影响加载效率。要求用户上传的图片之前压缩图片很影响用户体验,所以就增加了在前端进行图片压缩的需求。
压缩方案
前端图片压缩的主要思路就是将图片绘制到canvas中,然后通过canvas的toDataURL方法来控制图片的质量,对图片进行压缩,另一方面是对图片进行宽高等比缩小来达到图片压缩的效果,下面来看一下代码示例:
resizeMe(img,type, max_width, max_height) { var canvas = document.createElement('canvas'); var width = img.width; var height = img.height; max_width = !isNaN(max_width)?max_width:0; max_height = !isNaN(max_height)?max_height:0; // 在这里图片是等比例缩放的,调用方法时填入图片允许的最大宽度或者是最大的高度 //如果最大宽度为0 则按照最大高度固定,宽度自适应的方式来实现 //如果是最大高度为0,则按照最大的宽度来实现 if(max_width==0){ if (height > max_height) { width = Math.round(width *= max_height / height); height = max_height; } } if(max_height==0){ if (width > max_width) { height = Math.round(height *= max_width / width); width = max_width; } } canvas.width =width; canvas.height = height; var ctx = canvas.getContext("2d"); canvas.width =width; canvas.height = height; ctx.drawImage(img,0,0, width, height); type = type === 'jpg'?"jpeg":type; return canvas.toDataURL("image/"+type, 0.7);//这里的0.7值的是图片的质量 } 复制代码
在上面的代码中,我们传入的参数主要有image对象,图片类型,图片的最大宽度和最大高度。调用方法时填入图片允许的最大宽度或者是最大的高度,进行等比绘制到canvas中,然后通过toDataURL来转换成base64格式返回,此时的图片就是压缩过后的图片。
创建image对象
上面的示例说了图片压缩的过程,其中有一个参数是image对象,那么这个image对象是如何来的呢。
selectFileImage(el){ var reader = new FileReader(); var file = el.target.files[0] var fileName = file.name; var fileType = file.name.split(".")[1]; reader.readAsArrayBuffer(file); reader.onload = (ev) => { var blob = new Blob([ev.target['result']]); window['URL'] = window['URL'] || window['webkitURL']; var blobURL = window['URL'].createObjectURL(blob); var image = new Image(); image.src = blobURL; image.onload = (e) => { var thumb = this.resizeMe(image,fileType, 400, 0);//获得的路径是将图片转换成了base64 axios.post("http://127.0.0.1:3003/useasync/upload",{file:thumb,fileName:fileName}).then(res => { if (res.data.code == 200) { console.log(res) } else { console.log(res) } }); } } } 复制代码
在这里面我使用了一个FileReader对象,FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
当触发input的onChange事件后,可以读取到input中的file文件,于是将此文件读取到缓存当中,当读取完成后,result属性中保存的将是被读取文件的ArrayBuffer数据对象。这里我们可以看一下读取完成后的这个ev到底是个什么东西 我们可以看到这里面loaded和total都表示的是文件的总大小,重要的其实是target和currentTarget,这两个属性其实是一样的,里面包含了读取的fileReader对象,里面的result就是缓存中的数据了,我们通过new 一个Blob对象,将其转换为Blob对象,然后就可以通过url方法来将其转换为可以放到img src中的链接形式了。此时创建image对象,并对其src进行赋值,当image加载完成后,就开始调用压缩方法,传入的image对象就是我们刚才生成的image对象。
当压缩完成后返回的数据就是base64的数据了,我们就可以通过ajax异步来进行上传,在此我采用的是axios进行异步上传,将内容及文件名作为参数传递给后台。
后台接收
在这我才用的示例为nodejs搭建后台来接收图片,这里我们需要一个bodyParser模块
app.use(bodyParser.json({ limit:'5mb'}));//限制允许提交的大小 复制代码
将大小限制为5M以内,也就是说通过base64上传的图片大小一定要小于5M才能成功,这个参数我们可以随意更改,按业务需求而定。
router.post("/upload",function(req,res){ var imgData = req.body.file; var fileName = req.body.fileName; var base64Data = imgData.replace(/^data:image\/\w+;base64,/, ""); var dataBuffer = new Buffer(base64Data, 'base64'); fs.writeFile(process.cwd()+"/upload/"+fileName, dataBuffer, function(err) { if(err){ res.json({success:false,errormsg:err}); }else{ res.send({success:true,msg:"保存成功!"}); } }); }) 复制代码
接口中我们通过Buffer来将base64转换为buffer,进而保存到服务器本地中,本示例采用的就是将图片保存到服务器本地。如此通过将base64编码图片保存为图片就做完了。
由于压缩采用的是canvas,获取文件等是通过FileReader 对象及Bolb对象,故此方法目前的兼容性最低为IE10,还请酌情使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 前端实现图片压缩上传
- 图片纯前端JS压缩的实现
- itops代码优化之前端代码压缩
- 花椒前端用WebAssembly提升前端应用解压缩性能的尝试
- 花椒前端用 WebAssembly 提升前端应用解压缩性能的尝试
- tio-webpack 2.0.2 发布,传统前端的编译打包压缩工具
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
软件开发者路线图
Dave H. Hoover、Adewale Oshineye / 王江平 / 机械工业出版社 / 2010年9月 / 35.00元
作为一名软件开发者,你在奋力推进自己的职业生涯吗?面对今天日新月异和不断拓展的技术,取得成功需要的不仅仅是技术专长。为了增强专业性,你还需要一些软技能以及高效的学习技能。本书的全部内容都是关于如何修炼这些技能的。两位作者Dave Hoover和Adewale Oshineye给出了数十种行为模式,来帮你提高主要的技能。 本书中的模式凝结了多年的调查研究、无数次的访谈以及来自O’Reilly在......一起来看看 《软件开发者路线图》 这本书的介绍吧!