canvas教程

HTML5 file API加canvas实现图片前端JS压缩并上传

字号+ 作者:H5之家 来源:H5之家 2017-08-04 18:01 我要评论( )

HTML5 file API加canvas实现图片前端JS压缩并上传

这篇文章发布于 2017年07月30日,星期日,23:47,归类于js实例。 阅读 60 次, 今日 59 次

byzhangxinxu from ?p=6308

本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处,摘要引流则随意。

一、图片上传前端压缩的现实意义

对于大尺寸图片的上传,在前端进行压缩除了省流量外,最大的意义是极大的提高了用户体验。

这种体验包括两方面:

  • 由于上传图片尺寸比较小,因此上传速度会比较快,交互会更加流畅,同时大大降低了网络异常导致上传失败风险。
  • 最最重要的体验改进点:省略了图片的再加工成本。很多网站的图片上传功能都会对图片的大小进行限制,尤其是头像上传,限制5M或者2M以内是非常常见的。然后现在的数码设备拍摄功能都非常出众,一张原始图片超过2M几乎是标配,此时如果用户想把手机或相机中的某个得意图片上传作为自己的头像,就会遇到因为图片大小限制而不能上传的窘境,不得不对图片进行再处理,而这种体验其实非常不好的。如果可以在前端进行压缩,则理论上对图片尺寸的限制是没有必要的。
  • 二、图片前端JS压缩并上传功能体验

    特意制作了一个图片前端压缩并上传的完整demo,您可以狠狠的点击这里: 使用canvas在前端压缩图片并上传demo

    进入demo会看到一个相貌平平的文件输入框:

    itdadao

    啊,不对,应该是这张图:

    itdadao

    点击文件选择框,我们不妨选一张尺寸比较大的图片,例如下面这种2M多的钓鱼收获照:

    itdadao

    于是图片歘歘歘地传上去了:

    itdadao

    此时我们点击最终上传完毕的图片地址,会发现原来2M多3000多像素宽的图片被限制为400像素宽了:

    itdadao

    保存到本地会发现图片尺寸已经变成只有70K了:

    itdadao

    以上就是图片前端压缩并上传demo的完整演示。

    三、HTML5 file API加canvas实现图片前端JS压缩

    要想使用JS实现图片的压缩效果,原理其实很简单,核心API就是使用 canvas 的 drawImage() 方法。

    canvas 的 drawImage() 方法API如下:

    context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

    虽然看上去有9大参数,但不用慌,实际上可以看出就3个参数:

    img 就是图片对象,可以是页面上获取的DOM对象,也可以是虚拟DOM中的图片对象。 sx,sy,swidth,sheight 在 canvas 画布上画一片区域用来放置图片, sx,sy 为左上角坐标, swidth,sheight 指区域大小。如果没有指定后面4个参数,则图片会被拉伸或缩放在这片区域内。 x,y,width,height 就是图片在 canvas 画布上显示的大小和位置。如果这里的 width,height 的值就是图片的原始尺寸,则最终的表现效果是图片剪裁于 swidth,sheight 区域内。

    对于本文的图片压缩,最后四个参数是用不到的,取消前面五个参数就可以了。举个例子,一张图片(假设图片对象是 img )的原始尺寸是4000*3000,现在需要把尺寸限制为400*300大小,很简单,原理如下代码示意:

    var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); canvas.width = 400; canvas.height = 300; // 核心JS就这个 context.drawImage(img,0,0,400,300);

    把一张大的图片,直接画在一张小小的画布上。此时大图片就天然变成了小图片,压缩就这么实现了,是不是简单的有点超乎想象。

    当然,若要落地于实际开发,我们还需要做些其他的工作,就是要解决图片来源和图片去向的问题。

    1. 如何把系统中图片呈现在浏览器中?

    HTML5 file API可以让图片在上传之前直接在浏览器中显示,通常使用 FileReader 方法,代码示意如下:

    var reader = new FileReader(), img = new Image(); // 读文件成功的回调 reader.onload = function(e) { // e.target.result就是图片的base64地址信息 img.src = ; }; eleFile.addEventListener('change', function (event) { reader.readAsDataURL(event.target.files[0]); });

    于是,包含图片信息的 context.drawImage() 方法中的 img 图片就有了。

    2. 如果把canvas画布转换成img图像

    canvas 天然提供了2个转图片的方法,一个是:

    canvas.toDataURL()方法

    语法如下:

    canvas.toDataURL(mimeType, qualityArgument)

    可以把图片转换成base64格式信息,纯字符的图片表示法。

    其中:

    mimeType 表示 canvas 导出来的 base64 图片的类型,默认是png格式,也即是默认值是 'image/png' ,我们也可以指定为jpg格式 'image/jpeg' 或者webp等格式。 file 对象中的 file.type 就是文件的mimeType类型,在转换时候正好可以直接拿来用(如果有file对象)。

    qualityArgument 表示导出的图片质量,只要导出为 jpg 和 webp 格式的时候此参数才有效果,默认值是 0.92 ,是一个比较合理的图片质量输出参数,通常情况下,我们无需再设定。

    canvas.toBlob()方法 语法 如下: canvas.toBlob(callback, mimeType, qualityArgument)

    可以把canvas转换成Blob文件,通常用在文件上传中,因为是二进制的,对后端更加友好。

    和 toDataURL() 方法相比, toBlob() 方法是异步的,因此多了个 callback 参数,这个 callback 回调方法默认的第一个参数就是转换好的 blob 文件信息,本文demo的文件上传就是将 canvas 图片转换成二进制的 blob 文件,然后再 ajax 上传的,代码如下:

    // canvas转为blob并上传 canvas.toBlob(function (blob) { // 图片ajax上传 var xhr = new XMLHttpRequest(); // 开始上传 xhr.open("POST", 'upload.php', true); xhr.send(blob); });

    于是,经过“图片→canvas压缩→图片”三步曲,我们完成了图片前端压缩并上传的功能。

    更加完整的核心代码请参见demo页面的左侧,如果对其他交互代码也敢兴趣,请参考页面源代码。

    四、结束语

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • Android canvas绘制柱形统计图

      Android canvas绘制柱形统计图

      2017-08-05 09:02

    • 利用html5 canvas 画图的一个例子

      利用html5 canvas 画图的一个例子

      2017-08-04 16:00

    • HTML5 CANVAS画图 beginPath和closeP

      HTML5 CANVAS画图 beginPath和closeP

      2017-08-04 15:03

    • Canvas学习:自定义的坐标变换

      Canvas学习:自定义的坐标变换

      2017-08-04 13:02

    网友点评
    i