Home > Web Front-end > H5 Tutorial > body text

HTML5 mobile development image compression upload function

巴扎黑
Release: 2017-05-21 14:55:48
Original
2272 people have browsed it

When uploading pictures on the mobile terminal, users generally upload pictures from the mobile phone album. Now the shooting quality of mobile phones is getting higher and higher. Generally, the size of a single photo is around 3M. Therefore, it is necessary to perform local processing before uploading. compression. Below, the editor of Script House brings you the HTML5 mobile development image compression and upload function. Friends who are interested in the html5 image compression and upload function should take a look.

H5 activities are very common. One of the forms is Let users participate by uploading images. When uploading pictures on the mobile terminal, users usually upload pictures from the mobile phone album. Nowadays, the shooting quality of mobile phones is getting higher and higher, and the size of a single photo is generally around 3M. If you upload it directly, it consumes a lot of traffic and the experience is not good. Therefore, local compression needs to be performed before uploading.

Next, we will summarize the image compression and upload function in the development of h5 activities, and mark several pitfalls that we have encountered, and share them with everyone:

Must-see in Xiaobai District

If you have no idea about uploading images on the mobile terminal, you need to add the three concepts of FileReader, Blob, and FormData.

1.FileReader

Definition

Using the FileReader object, a web application can asynchronously read files (or raw Data buffer) content, you can use a File object or a Blob object to specify the file or data to be processed.

Method

Event handler

Use


var fileReader = new FileReader();
fileReader.onload = function() {
    var url = this.result;
}
//or
fileReader.onload = function(e) {
    var url = e.target.result;
}
Copy after login

2.Blob

BLOB (binary large object), A binary large object is a container that can store binary files.

3.FormData

Using the FormData object, you can use a series of key-value pairs to simulate a complete form, and then use XMLHttpRequest to send this "form".

The main topic

Mobile image compression upload process:

1) Input file to upload the image and use FileReader to read the user Uploaded images;

2) Pass the image data into the img object, draw the img onto the canvas, and then use canvas.toDataURL for compression;

3) Obtain the compressed base64 format image data , convert to binary, insert formdata, and finally submit formdata through xmlHttpRequest;

1. Get image data


fileEle.onchange = function() {
    if (!this.files.length) return;
    //以下考虑的是单图情况
    var _ua = window.navigator.userAgent;
    var _simpleFile = this.files[0];
    //判断是否为图片
    if (!/\/(?:jpeg|png|gif)/i.test(_simpleFile.type)) return;
    //插件exif.js获取ios图片的方向信息
    var _orientation;
    if(_ua.indexOf('iphone') > 0) {
        EXIF.getData(_simpleFile,function(){
            _orientation=EXIF.getTag(this,'Orientation');
        });
    }
    //1.读取文件,通过FileReader,将图片文件转化为DataURL,即data:img/png;base64,开头的url,可以直接放在image.src中;
    var _reader = new FileReader(),
        _img = new Image(),
        _url;
    _reader.onload = function() {
        _url = this.result;
        _img.url = _url;
        _img.onload = function () {
            var _data = compress(_img);
            uploadPhoto(_data, _orientation);
        };
    };
    _reader.readAsDataURL(_simpleFile);
};
Copy after login

2. Compress pictures


/**
 * 计算图片的尺寸,根据尺寸压缩
 * 1. iphone手机html5上传图片方向问题,借助exif.js
 * 2. 安卓UC浏览器不支持 new Blob(),使用BlobBuilder
 * @param  {Object} _img         图片
 * @param  {Number} _orientation 照片信息
 * @return {String}              压缩后base64格式的图片
 */
function compress(_img, _orientation) {
    //2.计算符合目标尺寸宽高值,若上传图片的宽高都大于目标图,对目标图等比压缩;如果有一边小于,对上传图片等比放大。
    var _goalWidth = 750,                  //目标宽度
        _goalHeight = 750,                 //目标高度
        _imgWidth = _img.naturalWidth,     //图片宽度
        _imgHeight = _img.naturalHeight,   //图片高度
        _tempWidth = _imgWidth,            //放大或缩小后的临时宽度
        _tempHeight = _imgHeight,          //放大或缩小后的临时宽度
        _r = 0;                            //压缩比
    if(_imgWidth === _goalWidth && _imgHeight === _goalHeight) {
    } else if(_imgWidth > _goalWidth && _imgHeight > _goalHeight) {//宽高都大于目标图,需等比压缩
        _r = _imgWidth / _goalWidth;
        if(_imgHeight / _goalHeight < _r) {
            _r = _imgHeight / _goalHeight;
        }
        _tempWidth = Math.ceil(_imgWidth / _r);
        _tempHeight = Math.ceil(_imgHeight / _r);
    } else {
        if(_imgWidth < _goalWidth && _imgHeight < _goalHeight) {//宽高都小于
            _r = _goalWidth / _imgWidth;
            if(_goalHeight / _imgHeight < _r) {
                _r = _goalHeight / _imgHeight;
            }
        } else {
            if(_imgWidth < _goalWidth) {         //宽小于
                _r = _goalWidth / _imgWidth;
            } else{                              //高小于
                _r = _goalHeight / _imgHeight;
            }
        }
        _tempWidth = Math.ceil(_imgWidth * _r);
        _tempHeight = Math.ceil(_imgHeight * _r);
    }
    //3.利用canvas对图片进行裁剪,等比放大或缩小后进行居中裁剪
    var _canvas = e._$get(&#39;canvas-clip&#39;);
    if(!_canvas.getContext) return;
    var _context = _canvas.getContext(&#39;2d&#39;);
    _canvas.width = _tempWidth;
    _canvas.height = _tempHeight;
    var _degree;
    //ios bug,iphone手机上可能会遇到图片方向错误问题
    switch(_orientation){
       //iphone横屏拍摄,此时home键在左侧
        case 3:
            _degree=180;
            _tempWidth=-_imgWidth;
            _tempHeight=-_imgHeight;
            break;
        //iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)
        case 6:
            _canvas.width=_imgHeight;
            _canvas.height=_imgWidth; 
            _degree=90;
            _tempWidth=_imgWidth;
            _tempHeight=-_imgHeight;
            break;
        //iphone竖屏拍摄,此时home键在上方
        case 8:
            _canvas.width=_imgHeight;
            _canvas.height=_imgWidth; 
            _degree=270;
            _tempWidth=-_imgWidth;
            _tempHeight=_imgHeight;
            break;
    }
    if(window.navigator.userAgent.indexOf(&#39;iphone&#39;) > 0 && !!_degree) {
        _context.rotate(_degree*Math.PI/180);
        _context.drawImage(_img, 0, 0, _tempWidth, _tempHeight); 
    } else {
        _context.drawImage(_img, 0, 0, _tempWidth, _tempHeight);
    }
    //toDataURL方法,可以获取格式为"data:image/png;base64,***"的base64图片信息;
    var _data = _canvas.toDataURL(&#39;image/jpeg&#39;);
    return _data;
}
Copy after login

3. Upload pictures


/**
 * 上传图片到NOS
 * @param  {Object} _blog Blob格式的图片
 * @return {Void}
 */
function uploadPhoto(_data) {
    //4.获取canvas中的图片信息
    //window.atob方法将其中的base64格式的图片转换成二进制字符串;若将转换后的值直接赋值给Blob会报错,需Uint8Array转换:最后创建Blob对象;
    _data = _data.split(&#39;,&#39;)[1];
    _data = window.atob(_data);
    //如果不用ArrayBuffer,发送给服务器的图片格式是[object Uint8Array],上传失败...
    var _buffer = new ArrayBuffer(_data.length);
    var _ubuffer = new Uint8Array(_buffer);
    for (var i = 0; i < _data.length; i++) {
        _ubuffer[i] = _data.charCodeAt(i);
    }
    // 安卓 UC浏览器不支持 new Blob(),使用BlobBuilder
    var _blob;
    try {
        _blob = new Blob([_buffer], {type:&#39;image/jpeg&#39;});
    } catch(ee) {
        window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
        if (ee.name == &#39;TypeError&#39; && window.BlobBuilder) {
            var _bb = new BlobBuilder();
            _bb.append(_buffer);
            _blob = _bb.getBlob(&#39;image/jpeg&#39;);
        }
    }
    var _suffix = &#39;jpg&#39;;
    if(_blob.type === &#39;image/jpeg&#39;) {
        _suffix = &#39;jpg&#39;;
    }
    //获取NOStoken
    this.__cache._$requestDWRByGet({url: &#39;ImageBean.genTokens&#39;,param: [_suffix,&#39;&#39;,&#39;&#39;,&#39;&#39;,&#39;1&#39;],onload: function(_tokens) {
        _tokens = _tokens || [];
        var _token = _tokens[0];
        if(!_token || !_token.objectName || !_token.uploadToken){
            alert(&#39;token获取失败!&#39;);
            return false;
        }
        //上传图片到NOS
        var _objectName = _token.objectName,
            _uploadToken = _token.uploadToken,
            _bucketName = _token.bucketName;
        var _formData = new FormData();
        _formData.append(&#39;Object&#39;, _objectName);
        _formData.append(&#39;x-nos-token&#39;, _uploadToken);
        _formData.append(&#39;file&#39;,_blob);
        var _xhr;
        if (window.XMLHttpRequest) {
            _xhr = new window.XMLHttpRequest();
        } else if (window.ActiveXObject) {
            _xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
        _xhr.onreadystatechange = function() {
            if(_xhr.readyState === 4) {
                if((_xhr.status >= 200 && _xhr.status < 300) || _xhr.status === 304) {
                    var _imgurl = "http://nos.netease.com/" + _bucketName + "/" + _objectName + "?imageView";
                    var _newUrl = mb.x._$imgResize(_imgurl, 750, 750, 1, true);
                    window.location.href = &#39;http://www.lofter.com/act/taxiu?op=effect&originImgUrl=&#39; + _newUrl;
                }
            }
        };
        _xhr.open(&#39;POST&#39;, &#39;http://nos.netease.com/&#39; + _bucketName, true);
        _xhr.send(_formData);
    }});
}
Copy after login

Plug-in to determine the direction of pictures taken by iPhone: exif

The above is the detailed content of HTML5 mobile development image compression upload function. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template