html5实现图片缩放,前端上传图片压缩
上一篇文章提到了移动端上传图片。我们知道现在流量还是挺贵的,手机像素也越来越高。拍一张照片要好几米,伤不起。虽然客户端可以很容易地实现图像压缩和上传,但我们的应用程序也可能在浏览器中打开。我该怎么办?图像压缩。受过去PC上开发思维的影响,尼玛js没有操作文件的权限,更没有压缩图片的资格。你做不到。继续在你的客户身上解决它。我只能说,我还是井底之蛙。在HTML5的影响下,前端可以做的事情越来越多,开发的功能也越来越高。H5万岁!前端的魅力也在这里。过去不可能的,不代表现在或未来不可能。好好干,骚年!
js如何压缩图片?在我的潜意识里,一开始真的觉得不可能实现。后来看了资料,研究了一下,发现可行!起来!
先说说我们在H5之前是怎么上传的吧。一般我们用插件,flash或者干脆一个文件形式的表单,不用太操心。
自从H5之后,我的老板不再担心我的发展。
上一篇文章提到在图片上传中使用了FileReader和FormData。其实用这两个基本就可以预览和上传图片了。要实现图像压缩,需要画布的帮助,对,画布!
总的想法是:
1、创建一个图片和一个canvas
XML/HTML代码将内容复制到剪贴板var image=newimage(),canvas=document . createelement( canvas ),CTX=canvas . get context( 2d );2、我们将input中选择的图片地址通过FileReader获取后赋给新建的图片对象,然后将图片对象丢到canvas画布上。
XML/HTML代码将内容复制到剪贴板varfile=obj . files[0];varreader=new filereader();//读取文件reader . onload=function(){ var URL=reader . result;//读取文件内容。此属性仅在读取操作完成后有效,数据的格式取决于读取操作的启动方法。所以必须使用reader.onload,image.src=url//reader读取的文件内容是base64,使用这个网址可以在上传前预览图片.};image . onload=function(){ varw=image . natural width,h=image.naturalHeightcanvas . width=w;canvas . height=h;ctx.drawImage(image,0,0,w,h,0,0,w,h);file upload();};reader.readAsDataURL(文件);
这里需要注意的是,canvas在画布上画图时,需要确定画布的大小,设置drawImage的参数,如下:
XML/HTML代码将内容复制到剪贴板void CTX。drawimage (image,sx,sy,swidth,sheight,dx,dy,dwidth,dheight);
目标画布上源图像左上角的dxX轴位置。
dy源图像左上角在目标画布Y轴上的位置。
在目标画布上绘制图像的宽度。允许缩放绘制的图像。如果没有说明,画图时不会缩放图片的宽度。
dWidth在目标画布上绘制的图像的高度。允许缩放绘制的图像。不解释的话,画的时候不会按比例缩放图片的高度。
需要绘制到目标上下文中的源图像的矩形选择框左上角的dHeightX坐标。
需要绘制到目标上下文中的源图像的矩形选择框左上角的sxY坐标。
sy需要绘制到目标上下文中的源图像的矩形选择框的宽度。如果不是,则整个矩形从坐标的sx和sy开始,到图像的右下角结束。
sWidth需要绘制到目标上下文中的源图像的矩形选择框的高度。
sHeight
为了上传完整的图片,这里dx,dy必须设置为0,dWidth和dHeight必须设置为原始图片的宽度和高度。这就是为什么我们需要等image对象下载完毕后获取其原始尺寸,这很关键!
XML/HTML代码将内容复制到剪贴板function file upload(){ var data=canvas . toda aurl( image/JPEG ,quality);//dataURL的格式为“data:image/png;Base64,**** "逗号前有一些解释性的词,我们只需要逗号后的那些datadata=data.split(,)[1];data=window.atob(数据);varia=new uint 8 array(data . length);for(vari=0;idata .长度;I){ ia[I]=data . charcode at(I);};//canvas.toDataURL返回的默认格式是image/png var blob=newblob ([ia],{ type: image/JPEG });varfd=new formdata();fd.append(myFile ,blob);varxhr=newXMLHttpRequest();xhr.addEventListener(load ,opts.success,false);xhr.addEventListener(error ,opts.error,false);xhr.open(POST ,opts . URL);xhr . send(FD);}这里使用的关键方法是canvas.toDataURL
XML/HTML代码将内容复制到剪贴板canvas.todataurl(类型,编码器选项);官方的描述是3、图片上传方法返回adata uri,其中包含由type参数指定的格式的图像表示(默认为ng)。返回的图像分辨率为96 dpi。其实就是在画布上看图的数据。默认情况下,它是png格式。如果第一个参数类型是image/jpeg,则第二个参数encoderOptions可用于设置图片的压缩质量。经过测试,如果是png格式,100%宽高可能会通过这种方法让图片变大~ ~ ~适得其反。所以我们可以在canvas.drawImage时适当设置sWidth和height,比如缩小1.5倍等。
还有一个奇怪的方法HTMLCanvasElement.toDataURL(),它的作用是解码,因为图像格式是base64。
XML/HTML代码将内容复制到剪贴板varencoded data=window . btoa(“hello,world”);//encode string vardecodedData=window . atob(encoded data);//decodethestring这个方法可能会解码一堆乱码,atob返回一个八进制整数数组。
Uint8Array,典型的Blob对象是图片或声音文件,其默认格式是PNG。
XML/HTML代码将内容复制到剪贴板var blob=newblob ([ia],{ type: image/JPEG });最后,Blob对象可以通过ajax发送到服务器。
整个过程大致如上,但是~ ~ ~实现后测试运行说“不是说图片压缩了吗?为什么图片上传还这么慢!”我拿起手机给妹纸演示。明明快了,我就说:“是因为你手机不行或者网络不好。当你下载图片时,它明显变小了。肯定比以前快了。看我第二关”。呵呵,毕竟还是在浏览器里偷偷查代码打时间日志好,比起压缩前的,尼玛!只快了几百毫秒!折腾半天,之前的代码已经重构好了。你在开玩笑吧。
细心的大神看了上面的代码也能猜到问题出在哪里。没错,Blob是存储二进制文件的容器
获取本地图片长宽尺寸的时候出了问题。
去,花了3174ms才拿到本地4M大小的图片尺寸!图越大用的时间越长~
代码将内容复制到剪贴板image . onload=function(){ varw=image . natural width,h=image.naturalheightcanvas . width=w/1.5;canvas . height=h/1.5;ctx.drawImage(image,0,0,w,h,0,0,w/1.5,h/1.5);Upload.fileUpload(类型);};浏览器在本地拍照时,无法像file.size那样直接获取其长宽,只能通过FileReader获取内容并赋给新创建的image对象。下载新创建的图像对象需要时间!怎么破?不就是拿到局部图片的大小吗?没有别的办法了吗?
于是想到了之前研究的博文,快速获取图片的长宽。演示地址:http://jsbin.com/jivugadure/edit? Html,js,输出,加载时定时检查图片的高度或宽度,无需等待整张图片加载完毕。
经过测试,还是不行,因为这种常规查询的方法对于常规服务器返回的图片是有效的。这里图片地址是base64,好像比较长~哭。
点击进入
1、用HTML5来压缩图片上传是可行的,在移动端我们不用依赖客户端或者插件,目前主流浏览器支持程度已经很高了。
2、压缩图片一方面是想减少用户上传等待的时间,另外也减少用户为此牺牲的流量,从整体时间来看,因为获取图片尺寸导致多一次下载需要耗时,其实压不压缩时间差别并不是特别大。除非大神们找到合适的方法能够直接获取图片的尺寸,麻烦也告知我一声,万分感谢;
3、既然时间成本差不多,但是我们压缩了图片,减少了图片的大小,减少了流量的消耗,存储空间以及下次获取该图片的时间,所以还是值得的。
小结一下:
Java Script语言代码复制内容到剪贴板(函数($){ $。扩展($。fn,{文件上传:函数(opts){ this。each(function(){ var $ self=$(this);varquality=opts.quality?opts.quality/100:0.2;vardom={ fileToUpload :$ self。查找(.fileToUpload )、 thumb:$self.find( .thumb ), progress:$self.find( .上传-进度)};varimage=newImage(),canvas=document。createelement( canvas ),CTX=画布。获取上下文(“2d”);var funs={ set imageurl:function(URL){ image。src=URL},绑定事件:function(){ console。日志(DOM。filetoupload)DOM。filetoupload。on( change ,funs函数(){ funs。文件选择(this);});},files elect:function(obj){ varfile=obj。文件[0];varreader=new filereader();读者。onload=function(){ varurl=reader。结果;funs.setImageUrl(网址);dom.thumb.html(图片);};形象。onload=function(){ varw=image。自然宽度,h=image.naturalHeightcanvas。宽度=w;画布。高度=h;ctx.drawImage(image,0,0,w,h,0,0,w,h);有趣。文件上传();};reader.readAsDataURL(文件);},文件上传:function(){ var data=canvas。toda taurl( image/JPEG ,质量);//数据统一资源定位器的格式为"数据:image/png;base64,* * * *,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了data=data.split(,)[1];data=window.atob(数据);varia=新的uint 8数组(数据。长度);for(vari=0;伊达。长度;I){ ia[I]=数据。charcode at(I);};//canvas.toDataURL返回的默认格式就是image/png varblob=newBlob([ia],{ type: image/JPEG });varfd=new formdata();fd.append(myFile ,blob);varxhr=newXMLHttpRequest();xhr.addEventListener(load ,opts.success,false);xhr.addEventListener(error ,opts.error,false);xhr.open(POST ,opts。网址);xhr。发送(FD);} };有趣。绑定事件();});} });})(Zepto);调用方式:
Java Script语言代码复制内容到剪贴板$(.文件上传).文件上传({ URL : savetofile。PHP , file:myFile , success :function(evt){ console。日志(evt。目标。responsetext)});希望大家能找到更好的办法,多多交流!感谢!
以上这篇深入研究HTML5实现图片压缩上传功能就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
原文地址:http://www。cn博客。com/胡图朱/p/5265023。超文本标记语言
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。