>  기사  >  웹 프론트엔드  >  HTML5 모바일 개발 이미지 압축 업로드 기능

HTML5 모바일 개발 이미지 압축 업로드 기능

巴扎黑
巴扎黑원래의
2017-05-21 14:55:482208검색

휴대폰에 사진을 업로드할 때, 사용자들은 일반적으로 휴대폰 앨범에서 사진을 업로드합니다. 이제 휴대폰의 촬영 품질이 점점 더 높아지고 있으며 일반적으로 사진 한 장의 크기가 3M 정도이므로 필요합니다. 압축하기 전에 로컬 처리를 수행합니다. 아래에서 Script House의 편집자가 HTML5 모바일 개발 이미지 압축 및 업로드 기능을 제공합니다. html5 이미지 압축 및 업로드 기능에 관심이 있는 친구들은 한 번 살펴보세요.

H5 활동이 매우 보편화되었습니다. 양식은 사용자가 이미지를 업로드하여 참여할 수 있도록 하는 것입니다. 모바일 단말기에 사진을 업로드할 때 사용자는 일반적으로 휴대전화 앨범에서 사진을 업로드합니다. 요즘 휴대전화의 촬영 품질이 점점 더 높아지고 있으며 사진 한 장의 크기는 일반적으로 3M 정도입니다. 직접 업로드하면 트래픽이 많이 소모되고 경험이 좋지 않습니다. 따라서 업로드하기 전에 로컬 압축을 수행해야 합니다.

다음으로 h5 활동 개발 중 이미지 압축 및 업로드 기능을 요약하고, 우리가 겪었던 몇 가지 함정을 표시하고 모두와 공유하겠습니다.

초보자 필독서

모바일 이미지 업로드에 대해 전혀 모른다면 FileReader, Blob, FormData의 세 가지 개념을 추가해야 합니다.

1.FileReader

정의

FileReader 개체를 사용하여 웹 애플리케이션은 파일(또는 원시 데이터 버퍼) 콘텐츠를 비동기식으로 읽을 수 있습니다. File 객체 또는 Blob 객체를 사용하여

메서드

이벤트 핸들러

사용


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

2.Blob

BLOB(Binary Large Object), Binary Large Object는 바이너리 파일을 저장할 수 있는 컨테이너입니다.

3.FormData

FormData 개체를 사용하면 일련의 키-값 쌍을 사용하여 전체 양식을 시뮬레이션한 다음 XMLHttpRequest를 사용하여 이 " form".

주제

모바일 이미지 압축 업로드 과정:

1) 이미지를 업로드할 파일을 입력하고 FileReader를 사용하여 사용자가 업로드한 이미지를 읽습니다.

2) 이미지 데이터를 img 개체에 전달하고 img를 캔버스에 그린 다음 압축을 위해 canvas.toDataURL을 사용합니다.

3) 압축된 base64 형식의 이미지 데이터를 얻고, 바이너리로 변환하고, formdata를 삽입하고, 마지막으로 xmlHttpRequest를 통해 formdata를 제출합니다.

1. 이미지 데이터 가져오기


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);
};

2. 사진 압축


/**
 * 计算图片的尺寸,根据尺寸压缩
 * 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;
}

3. 사진 업로드

/**
 * 上传图片到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);
    }});
}

iPhone으로 촬영한 사진의 방향을 결정하는 플러그인: EXIF

위 내용은 HTML5 모바일 개발 이미지 압축 업로드 기능의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.