添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • 利用 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计算消耗的时间也越长,可能会出现顿卡的情况。总之,就是这个过程当中需要花费一定时间。
  • IOS8.1的版本中有个FileReader的bug: FileReader读取的图片转化为Base64时,字符串为空,具体的问题描述请戳我

    步骤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请求。

    2月19日更新

    在安卓机器中,部分4.x的机型, 在webview里面对file对象进行了阉割,比如你拿不到file.type的值。

    2月22日更新

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

    封装好的github库,请戳我,如果觉得文章不错,请不要吝啬你的star~~

    嗯,fex-team提供的webuploader提供了jpegcoder.jsandriodpatch.js主要是来解决这个问题的。但是部分安卓机型对file对象进行了阉割,拿不到。

    @李惟 嗯,是。做一些内嵌到webview里面的H5页面的时候,遇到这种case的话,让端上提供bridge来进行图片的压缩,然后转成base64返回给你。然后再去完成图片的上传。

    我的是IPHONE6上传图片偶尔会出现页面回来后卡死的情况 但是不知道什么原因 没有固定的流程会导致这个问题 只是有时候就突然就出现了。我们测过 不是因为字符串过长的问题 有时候传同样的图片 有的卡死有的不卡死

    var initialize = function() { output = document.getElementById("output"); galleryImg2 = document.getElementById("galleryImg2"); galleryImg2.addEventListener('loadeddata',captureImage); var captureImage = function() { var canvas = document.createElement("canvas"); canvas.width = galleryImg2.videoWidth * scale; canvas.height = galleryImg2.videoHeight * scale; canvas.getContext('2d').drawImage(galleryImg2, 0, 0, canvas.width, canvas.height); var img = document.createElement("img"); img.src = canvas.toDataURL("image/png"); console.log(img); img.width = 79; img.height = 79; output.appendChild(img); initialize();
    var initialize = function() { output = document.getElementById("output"); galleryImg2 = document.getElementById("galleryImg2"); galleryImg2.addEventListener('loadeddata',captureImage); var captureImage = function() { var canvas = document.createElement("canvas"); canvas.width = galleryImg2.videoWidth * scale; canvas.height = galleryImg2.videoHeight * scale; canvas.getContext('2d').drawImage(galleryImg2, 0, 0, canvas.width, canvas.height); var img = document.createElement("img"); img.src = canvas.toDataURL("image/png"); console.log(img); img.width = 79; img.height = 79; output.appendChild(img); initialize(); 浙ICP备 15005796号-2   浙公网安备 33010602002000号

    CDN 存储服务由 又拍云 赞助提供