爱开发联盟是国内专业的网站建设资源、脚本编程学习类网站,提供asp、php、asp.net、javascript、jquery、vbscript、dos批处理、网页制作、网络编程、网站建设等编程资料。让开发变得简单起来!
爱开发联盟是国内专业的网站建设资源、脚本编程学习类网站,提供asp、php、asp.net、javascript、jquery、vbscript、dos批处理、网页制作、网络编程、网站建设等编程资料。让开发变得简单起来!
当前所在位置:主页 > 前端 > HTML5 >
  • 魔艺客提供SEO\SEM推广整合营销服务
  • 提供整套互联网营销整合方案-魔艺客
  • 魔艺客高端网站建设开发服务十一大优惠服务
  • 资深的网站建设开发经验,一对一服务-魔艺客高
  • 一站式服务,从服务器到网站,三站何以尽在魔
爱开发联盟是国内专业的网站建设资源、脚本编程学习类网站,提供asp、php、asp.net、javascript、jquery、vbscript、dos批处理、网页制作、网络编程、网站建设等编程资料。让开发变得简单起来!

深入研究HTML5实现图片压缩上传功能

发布时间:2017-09-01 20:58    作者:爱开发联盟    浏览:次    来源:aikaifa.com.cn 分享:

上篇文章中提到移动端上传图片,我们知道现在流量还是挺贵的,手机的像素是越来越高,拍个照动不动就是好几M,伤不起。虽然客户端可以轻轻松松实现图片压缩再上传,但是我们的应用还可能在浏览器里面打开,怎么办呢,图片压缩。受以前PC上的开发思维影响,尼玛js哪有权限去操作文件,哪有资格压缩图片啊,搞不了,你们客户端去整吧。只能说自己还是有些井底之蛙了。在HTML5的影响下,前端能干的事情越来越多了,开发的功能逼格也越来越高了,H5万岁!前端的魅力也在这,过去不可能的并不意味现在、以后不可能,努力吧,骚年!

js怎么压缩图片???潜意识里确实一开始是觉得实现不了,后来翻阅资料,研究了下,发现可行!搞起!

先说说H5以前我们怎么上传,一般是借助插件、flash或者干脆一个文件form表单,少操不少心。

自从有了H5,老板再也不担心我的开发了。

上篇文章提到图片上传用到了FileReader,FormData,实际上主要用这两个我们基本能实现图片的预览和上传了。实现图片压缩,我们需要借助canvas,是的,就是canvas!

大致思路是:

1、创建一个图片和一个canvas

XML/HTML Code复制内容到剪贴板
  1. var image = new Image(),   
  2. canvas = document.createElement("canvas"),   
  3. ctx = canvas.getContext('2d');  

2、我们将input中选择的图片地址通过FileReader获取后赋给新建的图片对象,然后将图片对象丢到canvas画布上。

XML/HTML Code复制内容到剪贴板
  1. var file = obj.files[0];   
  2.                         var reader = new FileReader();//读取客户端上的文件   
  3.                         reader.onload = function() {   
  4.                             var url = reader.result;//读取到的文件内容.这个属性只在读取操作完成之后才有效,并且数据的格式取决于读取操作是由哪个方法发起的.所以必须使用reader.onload,   
  5.                             image.src=url;//reader读取的文件内容是base64,利用这个url就能实现上传前预览图片   
  6.                             ...   
  7.                         };   
  8.                         image.onload = function() {   
  9.                             var w = image.naturalWidth,   
  10.                                 h = image.naturalHeight;   
  11.                             canvas.width = w;   
  12.                             canvas.height = h;   
  13.                             ctx.drawImage(image, 0, 0, w, h, 0, 0, w, h);   
  14.                             fileUpload();   
  15.                         };   
  16.                         reader.readAsDataURL(file);  


这里需要注意的是,canvas将图片画到画布上的时候需要确定canvas的尺寸,同时设定好drawImage的参数,具体如下:

XML/HTML Code复制内容到剪贴板
  1. void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);  

dx源图像的左上角在目标canvas上 X 轴的位置。

dy源图像的左上角在目标canvas上 Y 轴的位置。

dWidth在目标canvas上绘制图像的宽度。 允许对绘制的图像进行缩放。 如果不说明, 在绘制时图片宽度不会缩放。

dHeight在目标canvas上绘制图像的高度。 允许对绘制的图像进行缩放。 如果不说明, 在绘制时图片高度不会缩放。

sx需要绘制到目标上下文中的,源图像的矩形选择框的左上角 X 坐标。

sy需要绘制到目标上下文中的,源图像的矩形选择框的左上角 Y 坐标。

sWidth需要绘制到目标上下文中的,源图像的矩形选择框的宽度。如果不说明,整个矩形从坐标的sx和sy开始,到图像的右下角结束。

sHeight需要绘制到目标上下文中的,源图像的矩形选择框的高度。

为了上传完整的图片,这里dx,dy必须设置为0,dWidth和dHeight必须设置为原始图片的宽度和高度。这就是为什么我们需要等image对象下载完毕后获取其原始尺寸,这很关键!

3、图片上传

XML/HTML Code复制内容到剪贴板
  1. function fileUpload() {   
  2.      var data = canvas.toDataURL("image/jpeg", quality);   
  3.      //dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了   
  4.     datadata = data.split(',')[1];   
  5.     data = window.atob(data);   
  6.     var ia = new Uint8Array(data.length);   
  7.     for (var i = 0; i < data.length; i++) {   
  8.           ia[i] = data.charCodeAt(i);   
  9.     };   
  10.      //canvas.toDataURL 返回的默认格式就是 image/png   
  11.     var blob = new Blob([ia], {   
  12.      type: "image/jpeg"   
  13.     });   
  14.     var fd = new FormData();   
  15.         fd.append('myFile', blob);   
  16.     var xhr = new XMLHttpRequest();   
  17.     xhr.addEventListener("load", opts.success, false);   
  18.     xhr.addEventListener("error", opts.error, false);   
  19.     xhr.open("POST", opts.url);   
  20.     xhr.send(fd);   
  21.  }  

这里用的关键方法是canvas.toDataURL

XML/HTML Code复制内容到剪贴板
  1. canvas.toDataURL(type, encoderOptions);  

官方的说明是The HTMLCanvasElement.toDataURL() method returns a data URI containing a representation of the image in the format specified by the type parameter (defaults to PNG). The returned image is in a resolution of 96 dpi.实际上就是读取canvas画布上图片的数据。其默认是png格式,如果第一个参数type是image/jpeg的话,第二个参数encoderOptions就可以用来设置图片的压缩质量,经过测试,如果是png格式,100%的宽高经过该方法还有可能使图片变大~~~~适得其反,所以我们可以在canvas.drawImage的时候适当设置sWidth和sHeight,比如同比例缩小1.5倍等,图片质量其实并不太影响查看,尤其对尺寸比较大的图片来说。

上面还有比较陌生的方法atob,其作用是做解码,因为图片格式的base64.

XML/HTML Code复制内容到剪贴板
  1. var encodedData = window.btoa("Hello, world"); // encode a string   
  2. var decodedData = window.atob(encodedData); // decode the string  

该方法解码出来可能是一堆乱码,Uint8Array返回的是8进制整型数组。

Blob是存储二进制文件的容器,典型的Blob对象是一个图片或者声音文件,其默认是PNG格式。

XML/HTML Code复制内容到剪贴板
  1. var blob = new Blob([ia], {   
  2.      type: "image/jpeg"   
  3.     });  

最后通过ajax将Blob对象发送到server即可。

整个流程大致如上,但是~~~实现以后测试跑来说:“你不是说图片压缩了吗,为什么图片还是上传那么慢!”,哥拿起手机对妹纸演示了一下,明明很快嘛,于是反道“是你手机不行或者网络不好吧,你下载图片看明明变小了,比之前肯定快,你看我秒传”。呵呵,说归说,还是偷偷检查代码,在浏览器中打时间log,对比没压缩之前的,尼玛!!!居然才快了几百毫秒!!折腾了半天,之前的代码也重构了,玩我呢。

细心的大神看了上面的代码估计能猜出问题在哪,没错,获取本地图片长宽尺寸的时候出了问题。

我去,获取本地4M大小的图片尺寸花了3174ms!!,图片越大时间也越久~

JavaScript Code复制内容到剪贴板
  1. image.onload = function() {   
  2.         var w = image.naturalWidth,   
  3.           h = image.naturalHeight;   
  4.         canvas.width = w / 1.5;   
  5.         canvas.height = h / 1.5;   
  6.         ctx.drawImage(image, 0, 0, w, h, 0, 0, w / 1.5, h / 1.5);   
  7.         Upload.fileUpload(type);   
  8. };  

浏览器在本地取图片的时候是没法直接像file.size一样获取其长宽的,只能通过FileReader拿到内容后赋值给新建的image对象,新建的image对象下载需要时间!怎么破?不就是获取本地图片的尺寸吗,难道没有别的办法了?

于是想到了之前研究过的快速获取图片长宽的博文, ,demo地址:,定时去查询图片加载过程中的高度或者宽度,不用等整个图片加载完毕。

测了下,还是不行,因为定时查询这种方法对常规的server返回的图片有作用,这里图片地址是base64,貌似时间还更久了~哭。


小结一下:

1、用HTML5来压缩图片上传是可行的,在移动端我们不用依赖客户端或者插件,目前主流浏览器支持程度已经很高了。

2、压缩图片一方面是想减少用户上传等待的时间,另外也减少用户为此牺牲的流量,从整体时间来看,因为获取图片尺寸导致多一次下载需要耗时,其实压不压缩时间差别并不是特别大。除非大神们找到合适的方法能够直接获取图片的尺寸,麻烦也告知我一声,万分感谢;

3、既然时间成本差不多,但是我们压缩了图片,减少了图片的大小,减少了流量的消耗,存储空间以及下次获取该图片的时间,所以还是值得的。

 补充源代码:

JavaScript Code复制内容到剪贴板
  1. (function($) {   
  2.     $.extend($.fn, {   
  3.         fileUpload: function(opts) {   
  4.             this.each(function() {   
  5.                 var $self = $(this);   
  6.                 var quality = opts.quality ? opts.quality / 100 : 0.2;   
  7.                 var dom = {   
  8.                     "fileToUpload": $self.find(".fileToUpload"),   
  9.                     "thumb": $self.find(".thumb"),   
  10.                     "progress": $self.find(".upload-progress")   
  11.                 };   
  12.                 var image = new Image(),   
  13.                     canvas = document.createElement("canvas"),   
  14.                     ctx = canvas.getContext('2d');   
  15.                 var funs = {   
  16.                     setImageUrl: function(url) {   
  17.                         image.src = url;   
  18.                     },   
  19.                     bindEvent: function() {   
  20.                         console.log(dom.fileToUpload)   
  21.                         dom.fileToUpload.on("change"function() {   
  22.                             funs.fileSelect(this);   
  23.                         });   
  24.                     },   
  25.                     fileSelect: function(obj) {   
  26.                         var file = obj.files[0];   
  27.                         var reader = new FileReader();   
  28.                         reader.onload = function() {   
  29.                             var url = reader.result;   
  30.                             funs.setImageUrl(url);   
  31.                             dom.thumb.html(image);   
  32.                         };   
  33.                         image.onload = function() {   
  34.                             var w = image.naturalWidth,   
  35.                                 h = image.naturalHeight;   
  36.                             canvas.width = w;   
  37.                             canvas.height = h;   
  38.                             ctx.drawImage(image, 0, 0, w, h, 0, 0, w, h);   
  39.                             funs.fileUpload();   
  40.                         };   
  41.                         reader.readAsDataURL(file);   
  42.                     },   
  43.                     fileUpload: function() {   
  44.                         var data = canvas.toDataURL("image/jpeg", quality);   
  45.                         //dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了   
  46.                         data = data.split(',')[1];   
  47.                         data = window.atob(data);   
  48.                         var ia = new Uint8Array(data.length);   
  49.                         for (var i = 0; i < data.length; i++) {   
  50.                             ia[i] = data.charCodeAt(i);   
  51.                         };   
  52.                         //canvas.toDataURL 返回的默认格式就是 image/png   
  53.                         var blob = new Blob([ia], {   
  54.                             type: "image/jpeg"  
  55.                         });   
  56.                         var fd = new FormData();   
  57.                         fd.append('myFile', blob);   
  58.                         var xhr = new XMLHttpRequest();   
  59.                         xhr.addEventListener("load", opts.success, false);   
  60.                         xhr.addEventListener("error", opts.error, false);   
  61.                         xhr.open("POST", opts.url);   
  62.                         xhr.send(fd);   
  63.                     }   
  64.                 };   
  65.                 funs.bindEvent();   
  66.             });   
  67.         }   
  68.     });   
  69. })(Zepto);  

调用方式:

JavaScript Code复制内容到剪贴板
  1. $(".fileUpload").fileUpload({   
  2.                 "url""savetofile.php",   
  3.                 "file""myFile",   
  4.                 "success":function(evt){   
  5.                     console.log(evt.target.responseText)   
  6.                 }   
  7. });  

希望大家能找到更好的办法,多多交流!感谢!

以上这篇深入研究HTML5实现图片压缩上传功能就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

原文地址:

网友评论

分类排行榜联系我们

好文推荐联系我们

爱开发联盟是国内专业的网站建设资源、脚本编程学习类网站,提供asp、php、asp.net、javascript、jquery、vbscript、dos批处理、网页制作、网络编程、网站建设等编程资料。让开发变得简单起来!
爱开发联盟是国内专业的网站建设资源、脚本编程学习类网站,提供asp、php、asp.net、javascript、jquery、vbscript、dos批处理、网页制作、网络编程、网站建设等编程资料。让开发变得简单起来!

当前最新内容联系我们

爱开发联盟是国内专业的网站建设资源、脚本编程学习类网站,提供asp、php、asp.net、javascript、jquery、vbscript、dos批处理、网页制作、网络编程、网站建设等编程资料。让开发变得简单起来!

在线手册

网站地图导航

前端 HTML/Xhtml HTML5 CSS XML/XSLT Dreamweaver教程 Frontpage教程 心得技巧 编程 JavaScript ASP.NET PHP编程 正则表达式 AJAX相关 ASP编程 JSP编程 Flex 脚本加解密 web2.0 XML/RSS 网页编辑器 相关技巧 安全相关 网页播放器 Dart 其它综合 脚本 VBS DOS/BAT HTA HTC Python perl 游戏相关 vba 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 脚本下载 广告代码 js框架 批处理 网页相关 源码下载 数据库 MsSql Mysql mariadb oracle DB2 mssql2008 mssql2005 SQLite PostgreSQL MongoDB Redis Access 数据库文摘 数据库其它 CMS dedecms ecshop z-blog UcHome UCenter 风讯CMS 科汛cms discuz 新云cms phpwind 动易cms phpcms 帝国cms WordPress drupal 其它cms 设计 photoshop教程 摄影教程 Fireworks教程 CorelDraw教程 Illustrator教程 Painter教程 Freehand教程 Indesign 设计素材 平面其它 微信相关 微信公众号 小程序 操作系统 bios 系统安装 系统进程 Windows系列 LINUX RedHat/Centos Ubuntu/Debian Fedora Solaris 麒麟系统 红旗Linux Unix/BSD 苹果MAC 注册表 其它系统 网站运营 建站经验 微信营销 网站优化 网站策划 网络赚钱 网络创业 站长故事 alexa域名 其它相关 网络安全 黑客教程 安全设置 杀毒防毒 病毒查杀 脚本攻防 黑客入侵 工具使用 业界动态 Exploit 漏洞分析 加密解密 手机黑客 安全其它 在线手册 网页制作 脚本编程 数据库相关 软件编程 系统相关 其它相关 源码下载

友情链接申请加入

51CTO 上海魔艺客 猫鼬设计开发 Erlo网站开发 猫鼬设计工作室 新发现全球资讯 信息安全与IT资讯
爱开发联盟是国内专业的网站建设资源、脚本编程学习类网站,提供asp、php、asp.net、javascript、jquery、vbscript、dos批处理、网页制作、网络编程、网站建设等编程资料。让开发变得简单起来!

283882409