移动端 H5 图片压缩上传

标签: dev | 发表时间:2017-03-19 08:00 | 作者:
出处:http://itindex.net/admin/pagedetail

移动端H5图片压缩上传

大体的思路是,部分API的兼容性请参照 caniuse

  1. 利用 FileReader,读取 blob对象,或者是 file对象,将图片转化为 data uri的形式。
  2. 使用 canvas,在页面上新建一个画布,利用 canvas提供的API,将图片画入这个画布当中。
  3. 利用 canvas.toDataURL(),进行图片的压缩,得到图片的 data uri的值
  4. 上传文件。

步骤1当中,在进行图片压缩前,还是对图片大小做了判断的,如果图片大小大于200KB时,是直接进行图片上传,不进行图片的压缩,如果图片的大小是大于200KB,则是先进行图片的压缩再上传:

<input type="file"id="choose"accept="image/*">
varfileChooser=document.getElementById("choose"),
        maxSize=200*1024;//200KBfileChoose.change=function() {varfile=this.files[0],//读取文件reader=newFileReader();reader.onload=function() {varresult=this.result,//result为data url的形式img=newImage(),img.src=result;if(result.length<maxSize) {imgUpload(result);//图片直接上传}else{vardata=compress(img);//图片首先进行压缩imgUpload(data);//图片上传}
            }reader.readAsDataURL(file);
    }

步骤2,3:

varcanvas=document.createElement('canvas'),
        ctx=canvas.getContext('2d');functioncompress(img) {canvas.width=img.width;canvas.height=img.height;//利用canvas进行绘图//将原来图片的质量压缩到原先的0.2倍。vardata=canvas.toDataURL('image/jpeg',0.2);//data url的形式returndata;
    }

在利用canvas进行绘图的过程中,IOS图片上传过程中,存在着这样的问题:

  1. 当你竖着拿手机的时候,拍完照,上传图片时,会出现照片自动旋转的情况,而横着拍照并上传图片时不会出现这个问题。这个时候如果想纠正图片自动旋转的情况,将图片转化为二进制的数据 (使用了binaryajax.js),方便获取图片的 exif信息,通过获取 exif的信息来确定图片旋转的角度 (使用了exif.js),然后再进行图片相应的旋转处理。 解决方法请戳我
  2. IOS中,当图片的大小大于 2MB时,会出现图片压扁的情况,这个时候需要重置图片的比例。 解决方法请戳我
  3. 利用FileReader,读取图片的过程需要花费一定时间,将图片数据注入到canvas画布中需要一定时间,图片压缩的过程中,图片越大,CPU计算消耗的时间也越长,可能会出现顿卡的情况。总之,就是这个过程当中需要花费一定时间。
  4. IOS8.1的版本中有个 FileReader的bug: FileReader读取的图片转化为Base64时,字符串为空, 具体的问题描述请戳我, 遇到这个情况的话- - 还是老老实实把图片不做压缩处理扔给服务端吧.

步骤4,文件上传有2种方式:

  1. 将图片转化为 base64
  2. 将图片数据转为 Blob对象,使用 FormData上传文件

方式1可以通过 xhr ajax或者 xhr2 FormData进行提交。

方法2这里就有个大坑了。 具体描述请戳我

简单点说就是: Blob对象是无法注入到 FormData对象当中的。

当你拿到了图片的 data uri数据后,将其转化为 Blob数据类型

varndata=compress(img);
    ndata=window.atob(ndata);//将base64格式的数据进行解码//新建一个buffer对象,用以存储图片数据varbuffer=newUint8Array(ndata.length);for(vari=0; i<text.length; i++) {
        buffer[i]=ndata.charCodeAt(i);
    }//将buffer对象转化为Blob数据类型varblob=getBlob([buffer]);varfd=newFormData(),
        xhr=newXMLHttpRequest();fd.append('file', blob);xhr.open('post', url);xhr.onreadystatechange=function() {//do something}xhr.send(fd);

在新建 Blob对象中有需要进行兼容性的处理,特别是对于不支持 FormData上传 blob的andriod机的兼容性处理。 具体的方法请戳我主要实现的细节是通过重写HTTP请求。


2月19日更新

在安卓机器中, 部分机型不支持 JPEG格式的图片导出, 在 fex-team提供的 webuploader插件当中有个 jpegencoder.jsandroidpatch.js插件主要是解决这个问题, 链接请戳我,不过在部分 4.x的机型, 在 webview里面对 file对象进行了阉割,比如你拿不到 file.type的值。 唉- -。

2月22日更新

Android4.4<input type="file">由于系统 WebViewopenFileChooser接口更改,导致无法选择文件,从而导致无法上传文件. bug描述请戳我

使用

npm install
  npm run build
  • 支持AMD, CMD模块化的引入方式
  • 也可通过外链
canvasResize(this.files[0], {
      crop:false,//是否裁剪quality:0.9,//压缩质量  0 - 1rotate:0,//旋转角度callback(baseStr) {console.log(baseStr.length)
      }
    })

Some Tips

  • 在使用 FormData进行文件上传的时候,没有将图片文件转化为 blob,而是转为了 base64,主要是考虑到部分机型的兼容性的问题。
  • 在遇到一些是由于 native端上导致的问题的时候,比如在安卓 4.4.x的部分机型(主要集中在原生的系统,部门国产机,对 openFileChooser做过兼容)当中无法唤起选择图片或拍照的接口, 这个时候还是让 native的同学给你提供 bridge去完成图片的压缩和转码吧, 然后你再拿着端上给压缩好的图片去上传吧。
  • 封装好的库中没有提供裁剪的选项,如果需要有这方面的需求,请在 src/canvasResize.js里面做相应的修改(读读源码也挺好- -)。

使用到的库

相关 [移动 h5 图片] 推荐:

移动端 H5 图片压缩上传

- - IT瘾-dev
大体的思路是,部分API的兼容性请参照 caniuse:. 利用 FileReader,读取 blob对象,或者是 file对象,将图片转化为 data uri的形式. 使用 canvas,在页面上新建一个画布,利用 canvas提供的API,将图片画入这个画布当中. 利用 canvas.toDataURL(),进行图片的压缩,得到图片的 data uri的值.

H5 移动调试全攻略

- - IT瘾-dev
随着移动设备的高速发展, H5开发也成为了 F2E不可或缺的能力. 而移动开发的重中之重就是掌握调试技巧,定 Bug于无形. 文章首发于 Jartto’s blog,转载请标明出处. 因为移动端操作系统分为 iOS和 Android两派,所以本文的调试技巧也会按照不同的系统来区分.

移动H5前端性能优化指南

- - 腾讯ISUX - 社交用户体验设计 - Better Experience Through Design
移动H5前端性能优化指南[托尼托尼研究所]. PC优化手段在Mobile侧同样适用. 在Mobile侧我们提出三秒种渲染完成首屏指标. 基于第二点,首屏加载3秒完成或使用Loading. 基于联通3G网络平均338KB/s(2.71Mb/s),所以首屏资源不应超过1014KB. Mobile侧因手机配置原因,除加载外渲染速度也是优化重点.

H5 缓存机制浅析 移动端 Web 加载性能优化

- - SegmentFault 最新的文章
腾讯Bugly特约作者:贺辉超. H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性. 离线存储(也可称为缓存机制)是其中一个非常重要的特性. H5 引入的离线存储,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问. H5 应用程序缓存为应用带来三个优势:. 离线浏览 用户可在应用离线时使用它们.

使用 Fabric.js 玩转 H5 Canvas

- - V2EX - 技术
之前使用这个框架写过一个卡片 DIY 的项目,中间遇到很多问题都只能通过 google 或 github issues 才能解决,国内资料较少,所以才想写这篇文章来简单的做下总结,希望可以帮到其他人哈. 附上个人项目地址: vue-card-diy 欢迎 star~ ✨. 什么是 Fabric.js?.

H5与Native交互之JSBridge技术

- - SegmentFault 最新的文章
做过混合开发的很多人都知道Ionic和PhoneGap之类的框架,这些框架在web基础上包了一层Native,然后通过Bridge技术使得js可以调用视频、位置、音频等功能. 本文就是介绍这层Bridge的交互原理,通过阅读本文你可以了解到js与ios及android底层的通讯原理及JSBridge的封装技术及调试方法.

Hybrid 架构下的 H5 应用加速方案

- - 阿里巴巴(中国站)用户体验设计部博客
在移动 App 开发领域,主流的开发模式可分为 Native、Hybrid、WebApp 三种方式. 然而 2013 年,纯 WebApp 开发模式的发展受到一定挫折,以 Facebook 为代表的独立 App 转投 Native 阵营. 但是开发者对 WebApp 更新速度快,跨平台优势的渴望却并未减弱,最终的结果是促成了 Hybrid App 在 2013 年数量的激增,并且增长的速率非常之快.

如何做一个让人闻风丧胆的 H5

- - 腾讯ISUX - 社交用户体验设计 - Better Experience Through Design
最近火热的有声娱乐平台 APP,企鹅 FM,在8月28日鬼节前夕,联合《盗墓笔记》推出了“勇敢者的游戏”活动. 作为一个 UI 工程师,在这个移动互联网叱咤风云的时代,每次看到朋友圈中被分享的各种花样 H5 页面,总是心痒难耐,也想做有着酷炫动画和带感声效的 H5 呢. 回想到做鬼节活动页的时候,接近午夜零点还在调整页面效果,看着页面上渐隐渐现的可怕画面,活生生吓到了自己,也是蛮难忘的.

h5调用底层接口的一些知识

- - 神刀安全网
     前端时间使用HTML5做了一个WEB端APP,其中用到了H5页面调用手机摄像头的功能,当时也是花了不少时间去研究. 最终是采用了HTML5plus(HTML5+)的方式完成了该功能,现将具体方法简单介绍下,并讲解下使用的注意事项. 放在服务器上然后浏览就可以了,只支持Chrome和Safari核的浏览器,QQ浏览器,Chrome,Safari浏览器都可以.

视频H5のVideo标签在微信里的坑和技巧

- - JDC | 京东设计中心
随着 4G 的普遍以及 WiFi 的广泛使用,手机上的网速已经足够稳定和高速,以视频为主的 HTML5 也越来越普遍了,相比帧动画,视频的表现更加丰富,前段时间开发了一个以视频为主的移动端 HTML5,在这里介绍一些实践经验. 我们希望视频播放时可以全屏播放,没有进度条、播放按钮等与系统相关的元素,可以在视频上方增加自定义的元素(比如一个跳过按钮),类型下面的效果:.