好多H5活动让咱们上传图片,但手机拍的总是太大,传起来麻烦。那就让我们先压缩图片再上传。今天就来教大家咋弄还会和你们说说那些曾经做过的傻事以及补救措施哟。
了解基础概念
想学会如何传手机里的照片?先得明白FileReader、Blob和FormData这几个家伙,它们在网站浏览时很关键。比如FileReader就像是个眼睛,帮你看看电脑里有些啥文件;Blob这个大家伙就是个大口袋,啥二进制文件都能塞进去;最后说说FormData,它就像个虚拟表格,用起来特方便,还能直接传文件!
FileReader的用法
FileReader真的是个牛逼神器!它可以帮你快速从文件里取内容,超快的!使用时别忘了加点编程技巧,例如onload和onprogress这类事件,这样就能随时掌握文件进度!
Blob的作用
DB块儿就是放超大文件的地方,我们发图的时候,它可是能保证咱们的资料不会丢!
FormData的使用
FormData这个神器可以模拟一个假表单,然后我们用XMLHttpRequest直接发送数据给服务器。比如发图片的话,我们只需要操作一下FormData,然后上传缩小的照片即可。
var fileReader = new FileReader(); fileReader.onload = function() { var url = this.result; } //or fileReader.onload = function(e) { var url = e.target.result; }
图片压缩上传的步骤
压缩图片其实挺好玩!先叫用户选张要处理的宝贝图片,然后用FileReader读出那个文件,之后就交给img这个小伙伴处理压缩,最终,把压缩过的图弄成二进制藏在FormData里,再用XMLHttpRequest上传,搞定!
获取图片数据
选好图后,就得懂怎么读它了,这不难,只要用个FileReader工具,用户选中的图就能快速打开,看清楚里面是啥了!
压缩图片
别小看压缩图片这事咱们得了解下照片跟img究竟是咋回事儿,把照片的所有信息都交给img。然后,用canvas把这img画出来。搞定图片尺寸和清晰度后,大功告成!最后,你就会拥有一张美妙的压缩图片!
上传图片
终于嗷~完成了最后一步!先把之前压缩好的照片数据转换成二进制格式,接着直接加到FormData里就完事儿。之后就交给XMLHttpRequest帮你负责发出去好了,轻轻松松就能传好照片!
处理iPhone图片方向
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); };
拍照时不小心对焦错了怎么办?不用怕,iPhone能记住那张照片的朝向。只要安装个exif小插件,你上传后的照片就不会歪!
总结和问题
/** * 计算图片的尺寸,根据尺寸压缩 * 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 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('image/jpeg'); return _data; }
实话实说,在H5活动里上传图片其实很简单!首先,你得弄清楚怎么处理FileReader、Blob和FormData这几个东东;接着,就是稍微懂点HTML和JS。当然,有时候可能会遇到些小问题,比如图片乱七八糟之类的,但别担心,慢慢解决就好。
最近大家发现啥用H5编辑活动图片的困扰吗?来这儿跟大家唠嗑!别忘记给个赞或者分享哟~
/** * 上传图片到NOS * @param {Object} _blog Blob格式的图片 * @return {Void} */ function uploadPhoto(_data) { //4.获取canvas中的图片信息 //window.atob方法将其中的base64格式的图片转换成二进制字符串;若将转换后的值直接赋值给Blob会报错,需Uint8Array转换:最后创建Blob对象; _data = _data.split(',')[1]; _data = window.atob(_data); //如果不用ArrayBuffer,发送给服务器的图片格式是[object Uint8Array],上传失败... var _buffer = new ArrayBuffer(_data.length); var _ubuffer = new Uint8Array(_buffer); for (var i = 0; i = 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 = 'http://www.lofter.com/act/taxiu?op=effect&originImgUrl=' + _newUrl; } } }; _xhr.open('POST', 'http://nos.netease.com/' + _bucketName, true); _xhr.send(_formData); }}); }
评论0