首頁 > web前端 > H5教程 > 透過HTML5行動開發實現圖片壓縮上傳的功能

透過HTML5行動開發實現圖片壓縮上傳的功能

不言
發布: 2018-06-12 17:23:18
原創
2042 人瀏覽過

這篇文章主要介紹了透過HTML5行動開發實現圖片壓縮上傳的功能,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

行動端上傳圖片,用戶一般都是上傳手機相簿中的圖片,而現在手機的拍攝品質越來越高,一般單張照片的尺寸都在3M左右,因此需要在上傳之前,先進行本地壓縮。

H5活動已十分普遍,其中一種形式是讓用戶上傳圖片參與。行動端上傳圖片,用戶一般都是上傳手機相簿中的圖片,而現在手機的拍攝品質越來越高,一般單張照片的尺寸都在3M左右。若直接上傳,十分耗流量,體驗效果也不佳。因此需要在上傳之前,先進行本地壓縮。

接下來總結在h5活動的開發中圖片壓縮上傳的功能,並標記其中踩過的幾個坑,分享給大家:

#小白區必看

對於行動端圖片上傳毫無概念的話,需要補充FileReader、Blob、FormData三個概念。

1.FileReader

定義

使用FileReader物件,web應用程式可以異步的讀取儲存在使用者電腦上的檔案(或原始資料緩衝)內容,可以使用File物件或Blob物件來指定所要處理的檔案或資料.

方法

##事件處理程序

使用

1

2

3

4

5

6

7

8

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),二進位大對象,是一個可以儲存二進位檔案的容器。

3.FormData

利用FormData物件,你可以使用一系列的鍵值對來模擬一個完整的表單,然後使用XMLHttpRequest發送這個」表單”.

正題

行動裝置圖片壓縮上傳過程:

1)input file上傳圖片,使用FileReader讀取用戶上傳的圖片;

2)圖片資料傳入img對象,將img繪製到canvas上,再使用canvas.toDataURL進行壓縮;

3)取得壓縮後的base64格式圖片數據,轉成二進制,塞進formdata,最後透過xmlHttpRequest提交formdata;

#1.取得圖片資料

##

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

/**

 * 计算图片的尺寸,根据尺寸压缩

 * 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.上傳圖片

##

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

/**

 * 上传图片到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

以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!

相關推薦:

使用html5 canvas封裝一個echarts實作不了的餅圖

關於HTML5 input placeholder 的顏色修改


#

以上是透過HTML5行動開發實現圖片壓縮上傳的功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板