移动端H5图片上传的bug注意事项分析

上周做一个关于移动端图片压缩上传的功能。期间踩了几个坑,在此总结下。

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

利用FileReader,读取blob对象,或者是file对象,将图片转化为data uri的形式。
使用canvas,在页面上新建一个画布,利用canvas提供的API,将图片画入这个画布当中。
利用canvas.toDataURL(),进行图片的压缩,得到图片的data uri的值
上传文件。
步骤1当中,在进行图片压缩前,还是对图片大小做了判断的,如果图片大小大于200KB时,是直接进行图片上传,不进行图片的压缩,如果图片的大小是大于200KB,则是先进行图片的压缩再上传:

 代码如下 复制代码
<input type="file" id="choose" accept="image/*">
    var fileChooser = document.getElementById("choose"),
        maxSize = 200 * 1024;   //200KB
    fileChoose.change = function() {
        var file = this.files[0],   //读取文件
            reader = new FileReader();
           
            reader.onload = function() {
                var result = this.result,   //result为data url的形式
                    img = new Image(),
                    img.src = result;
                   
                   
                if(result.length < maxSize) { 
                    imgUpload(result);      //图片直接上传
                } else {
                    var data = compress(img);    //图片首先进行压缩
                    imgUpload(data);                //图片上传
                }
            }
           
            reader.readAsDataURL(file);
    }

步骤2,3:

 代码如下 复制代码
    var canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');
       
    function compress(img) {
        canvas.width = img.width;
        canvas.height = img.height;
       
        //利用canvas进行绘图
       
        //将原来图片的质量压缩到原先的0.2倍。
        var data = canvas.toDataURL('image/jpeg', 0.2); //data url的形式
       
        return data;
    }

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

当你竖着拿手机的时候,拍完照,上传图片时,会出现照片自动旋转的情况,而横着拍照并上传图片时不会出现这个问题。这个时候如果想纠正图片自动旋转的情况,将图片转化为二进制的数据(使用了binaryajax.js),方便获取图片的exif信息,通过获取exif的信息来确定图片旋转的角度(使用了exif.js),然后再进行图片相应的旋转处理。解决方法请戳我
在IOS中,当图片的大小大于 2MB时,会出现图片压扁的情况,这个时候需要重置图片的比例。解决方法请戳我
利用FileReader,读取图片的过程需要花费一定时间,将图片数据注入到canvas画布中需要一定时间,图片压缩的过程中,图片越大,CPU计算消耗的时间也越长,可能会出现顿卡的情况。总之,就是这个过程当中需要花费一定时间。
步骤4,文件上传有2种方式:

将图片转化为base64
将图片数据转为Blob对象,使用FormData上传文件
方式1可以通过xhr ajax或者xhr2 FormData进行提交。

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

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

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

 代码如下 复制代码

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

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

时间: 2024-11-08 19:14:42

移动端H5图片上传的bug注意事项分析的相关文章

移动端html5图片上传方法【更好的兼容安卓IOS和微信】_Android

之前的移动端上传的方法,有些朋友测试说微信支持不是很好,还有部分安卓机也不支持,其实我已经有了另一个方法,但是例子还没整理出来,而联系我的很多朋友需要,所以就提前先发出来了,并且做一个简单的说明,就不做一个demo了. <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=dev

移动端html5图片上传方法【更好的兼容安卓IOS和微信】

之前的移动端上传的方法,有些朋友测试说微信支持不是很好,还有部分安卓机也不支持,其实我已经有了另一个方法,但是例子还没整理出来,而联系我的很多朋友需要,所以就提前先发出来了,并且做一个简单的说明,就不做一个demo了. <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=dev

HTML5 移动端图片上传的实践

主要的思路是这样: 监听一个 input (type='file') 的 change 事件,然后拿到文件的 file; 把 file 转成 dataURL: 然后用 canvas 绘制图片,绘制的时候经过算法按比例裁剪; 然后再把 canvas 转成 dataURL; 再把 dataURL 转成 blob; 接着把 blob append 到 FormData 的实例对象. 最后上传. 主要用到的 FileReader.canvas.FormData.Blob 这几个 API. 开发过程遇到了

jQuery移动端图片上传组件_jquery

本文实例为大家分享了移动端图片上传组件,供大家参考,具体内容如下 Imageupload使用File API+canvas 客户端压缩图片,并实现文件上传服务端 文件依赖 JQUERY 参数API loading:'.loading', 页面显示loading的图标selector url:'', 接收数据的api接口地址 maxFileSize:1010241024, 服务端支持的最大单文件大小 format:/^image/i, 支持的文件格式. images text ..... isCo

C#实现图片上传(PC端和APP)保存及 跨域上传说明_C#教程

A-PC端: 1-页面--multiple是控制单张还是多张图片上传 <input id="BusRoute" type="file" class="btn btn-default btn-lg" style="height:34px;padding-top:5px;padding-bottom:5px;" multiple /> 2-后台获取图片文件: HttpFileCollection pcFileColl

dwz前端框架+ssh后天框架 如何实现图片上传

问题描述 dwz前端框架+ssh后天框架 如何实现图片上传 我写了一个案例,但是后台action获取不到文件流,可是,我单独调用这个页面时候,就可以获取到文件流,我真心不知道怎么处理了?是不是由于本框架的原因呢? 不知道大神们有没有好一点的上传案例或者解决方案.我用的是比较落后的DWZ中uploadify多文件上传? 急急急!!!!! 解决方案 我做的公司运营平台也是dwz前端框架+ssh,废话不说,解决方案如下.给你提供个项目遇到的实例,不懂可以再问我哈: 1,首先,封装了一个上传文件(包含图

js HTML5多图片上传及预览实例解析(不含前端的文件分割)_javascript技巧

本文实例为大家分享了js HTML5多图片上传及预览实例,供大家参考,具体内容如下 主要运用  1.HTML5 files可以选择多文件,以及获取多文件信息  2.XMLHTTPRequest对象,发送HTTP传输请求  3.将每一个文件放在FormData,进行传输  4.利用readAsDataURL将图片内容直接变成url,放在img标签的src当中,生成可预览的图片  html+css+js代码  <!DOCTYPE html> <head> <meta http-e

周末大放送网站图片上传,水印,预览,截图

    周末闲着没事,将网站中经常用到的对图片的操作做了一个总结,方便以后回顾,这里将一天的成果,贴出来,希望能帮到大家.     首先是swfupload方式的无刷新上传,关于怎么配置,按照demo 的写法,我相信只要你不是太笨,都能成功.     关于swfupload你可以去网上下,也可以点这里下载:SWFUpload_v250_beta_3_samples.rar    项目结构:               上传代码: 前台上传页面,你可以根据需要建html页,也可以建webform.

html5-求手机端图片上传组件

问题描述 求手机端图片上传组件 最近做了一个基于微信的移动端小项目,目前需要实现一个图片的上传功能,一共需要上传4张图片,目前html自带的文件域虽然可以实现,但四张图片同时提交恐怕会很慢,同时这样做图片上传也没有进度条效果,显得很单调,想在网上找一个上传组件,html5也好,不知道哪位大牛能够给我提供一个移动端兼容性最好的图片上传组件,代码最精简易懂,我后台是用PHP需要开发的,最好有一个完整的案例,我网上找了好多基本上没有看到满意的,求大神帮忙,这个问题困扰我好久了,知道的一定要给我回复,谢