Heim  >  Artikel  >  Web-Frontend  >  Entwicklungsprozess zum Hochladen mobiler H5-Bildkomprimierung

Entwicklungsprozess zum Hochladen mobiler H5-Bildkomprimierung

高洛峰
高洛峰Original
2016-12-07 13:19:102502Durchsuche

H5-Aktivitäten sind weit verbreitet und eine der Formen besteht darin, Benutzern das Hochladen von Bildern zur Teilnahme zu ermöglichen. Beim Hochladen von Bildern auf das mobile Endgerät laden Benutzer normalerweise Bilder aus dem Mobiltelefonalbum hoch. Heutzutage wird die Aufnahmequalität von Mobiltelefonen immer höher und die Größe eines einzelnen Fotos liegt im Allgemeinen bei etwa 3 Millionen. Wenn Sie es direkt hochladen, verbraucht es viel Verkehr und die Erfahrung ist nicht gut. Daher muss vor dem Hochladen eine lokale Komprimierung durchgeführt werden.

Als nächstes werden wir die Bildkomprimierungs- und Upload-Funktion bei der Entwicklung von h5-Aktivitäten zusammenfassen, einige Fallstricke markieren, auf die wir gestoßen sind, und sie mit allen teilen:

Ein Muss für Bezirk Xiaobai

Wenn Sie keine Ahnung vom mobilen Hochladen von Bildern haben, müssen Sie die drei Konzepte FileReader, Blob und FormData hinzufügen.

1.FileReader

Definition

Mithilfe des FileReader-Objekts können Webanwendungen den Inhalt von Dateien (oder Rohdatenpuffern), die auf dem Computer des Benutzers gespeichert sind, asynchron lesen Objekt oder Blob-Objekt, um die zu verarbeitende Datei oder Daten anzugeben

Methode

Entwicklungsprozess zum Hochladen mobiler H5-Bildkomprimierung

Ereignishandler

Verwendung

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), ein binäres großes Objekt, ist ein Container, der Binärdateien speichern kann.

3.FormData

Mit dem FormData-Objekt können Sie eine Reihe von Schlüssel-Wert-Paaren verwenden, um ein vollständiges Formular zu simulieren, und dann XMLHttpRequest verwenden, um dieses „Formular“ zu senden.

Hauptthema

Prozess zum Hochladen mobiler Bilder:
1) Eingabedatei zum Hochladen von Bildern, Verwenden Sie FileReader, um die von Benutzern hochgeladenen Bilder zu lesen;
2) Bild Daten werden an das IMG-Objekt übergeben, das IMG auf die Leinwand gezeichnet und dann zum Komprimieren verwendet.
3) Holen Sie sich die komprimierten Bilddaten im Base64-Format, konvertieren Sie sie in eine Binärdatei, stopfen Sie sie in Formdaten und senden Sie sie schließlich ab die Formdaten über xmlHttpRequest;

1. Bilddaten abrufen

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. Bilder komprimieren

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

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

Plug-in zur Bestimmung der Richtung der vom iPhone aufgenommenen Bilder: exif

Damit ist der H5-Bildkomprimierungs- und Hochladevorgang abgeschlossen.


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn