在经过前面的改进之后本来以为已经没有问题了,但经过我们神通广大的测试的测试,发现相册中的图片在上传时也会发生转向问题。既然前面都解决了拍照转向的问题,那么相册中图片的上传也容易解决。修改一下需要旋转图片的类型判定即可,修改如下:
var type = file.name.match(/\.\w+$/)[0].toLowerCase(); if (type == ".jpg" || type == ".jpeg")
凡是jpg类型的图片都要旋转,经过测试,相册中的单张上传是可以的,但批量上传的功能竟然失效了。用fiddler抓包发现,上传的base64字符串是包含多张图片,以至于后台代码在解析字符串时出错。再次阅读代码可以发现,代码中包还了多个异步操作,如使用FileReader、ajax上传图片、图片信息获取( EXIF.getData)、图片加载(img.onload)等。使用异步可以提高代码的执行效率,但是也往往会带来资源竞争的问题,我决定在一张图片读完之后再读取下一张图片,for循环显然是不可行了,我使用了递归来保证了这一点,修改代码如下:
1 (function () { 2 var imgOperate = { 3 operateUrl: "数据库操作地址", 4 uploadUrl: "上传图片地址", 5 DelPicId: '', 6 ddWidth: 0, 7 dlWidth: 0, 8 successCount:0, 9 onload: function () { 10 this.initImage(); 11 }, 12 initImage: function () { 13 var et = $('#entrust dd').length; 14 this.ddWidth = $('#entrust dd').width() + 17; 15 this.dlWidth = parseInt(et * this.ddWidth + 160); 16 $('#entrust').css("width", this.dlWidth); 17 this.BindEvent(); 18 }, 19 BindEvent: function () { 20 var _this = this; 21 $("#pic0").on("change", function () { 22 _this.uploadFiles(this); 23 24 }); 25 26 }, 27 InserImage:function(urls,dd) 28 { 29 $.post(this.operateUrl, { houseid: houseid, operateType: 1, picStr: urls }, function (data) { 30 data = eval("(" + data + ")"); 31 if (data && data.picIds) 32 { 33 dd.getElementsByTagName("img")[0].setAttribute("housepicid", data.picIds); 34 } 35 }); 36 }, 37 uploadFiles: function (where) { 38 if (!houseid) { 39 this.ShowMsg("请回到第一步完善相应的信息"); 40 return; 41 } 42 var imgLength = $("#entrust dd").length - 1; 43 44 if (imgLength >= 20) 45 { 46 this.ShowMsg("你的图片超过了20张,不能再上传"); 47 return; 48 } 49 if (imgLength + where.files.length > 20) 50 { 51 this.ShowMsg("你选择的图片超过了20张,无法上传,请重新选择"); 52 return; 53 } 54 55 56 var _this = this; 57 var radtime = new Date(); 58 var sid = radtime.getTime(); 59 this.successCount = 0; 60 this.UploadNext(0, sid, where); 61 }, 62 UploadNext: function (i, sid, where) 63 { 64 if (i >= where.files.length) return; 65 var file = where.files[i]; 66 var type = file.name.match(/\.\w+$/)[0].toLowerCase(); 67 if (type == ".jpg" || type == ".jpeg") { 68 this.UploadJpg(i, sid, where); 69 } else { 70 var formData = new FormData(); 71 formData.append("icoimage", file); 72 this.UploadImg(where, formData, sid, i); 73 i++; 74 this.UploadNext(i++, sid, where); 75 } 76 77 }, 78 UploadJpg:function(i,sid,where) 79 { 80 var _this = this; 81 var file = where.files[i]; 82 EXIF.getData(file, function () { 83 var formData = new FormData(); 84 85 EXIF.getAllTags(this); 86 var orientation = EXIF.getTag(this, 'Orientation'); 87 88 if (orientation && orientation >= 2 && orientation<=8) { 89 var reader = new FileReader(); 90 reader.readAsDataURL(file); 91 reader.onload = function (e) { 92 _this.getImgData(e, this.result, orientation, function (data) { 93 formData.append("icoimage", data); 94 _this.UploadImg(where, formData, sid, i); 95 i++; 96 _this.UploadNext(i, sid, where); 97 98 }); 99 }100 101 } else {102 103 formData.append("icoimage", file);104 _this.UploadImg(where, formData, sid, i);105 i++;106 _this.UploadNext(i, sid, where);107 108 }109 });110 },111 UploadImg: function (where, formData, sid, i) {112 var _this = this;113 $.ajax({114 url: this.uploadUrl + '?channel=duanzu.houseinfo&sid=' + sid,115 type: 'POST',116 cache: false,117 data: formData,118 processData: false,119 contentType: false120 }).success(function (res) {121 var imgsrc = res; 122 if (imgsrc == "-1" || imgsrc == "302" || imgsrc == -1 || imgsrc == 302) {123 _this.ShowMsg("上传失败,照片超过10M");124 } else if (imgsrc.indexOf("http") != -1) {125 var dd = document.createElement("dd");126 if ($("#entrust dd").length == 1) {127 dd.innerHTML = "<div class=\"cver\">封面图</div><a class=\"close\"></a><img src='/images/loading.gif' data-original=\"" + imgsrc + "\" housepicid=\"\">";128 } else {129 dd.innerHTML = "<a class=\"close\"></a><img src='/images/loading.gif' data-original=\"" + imgsrc + "\" housepicid=\"\">";130 }131 document.getElementById("entrust").appendChild(dd);132 _this.dlWidth += _this.ddWidth + 17;133 $('#entrust').css("width", _this.dlWidth);134 _this.InserImage(imgsrc, dd);135 this.successCount++;136 _this.ShowMsg("正在上传第" + (i+1)+ "张图片");137 }138 if (i == where.files.length) {139 if (this.successCount > 0) {140 _this.ShowMsg("成功上传" + successCount + ",可继续上传新照片");141 }142 } 143 })144 },145 ShowMsg: function (text, mymethod) {146 var radtime = new Date();147 var sid = radtime.getTime();148 var msg_div = "<div class='zuopenbox' id='div_msg" + sid + "'><div class='opencon_01'><div class='openList'><h3 class='f15' style='margin-bottom: 0; color: #FFFFFF'>" + text + "</h3></div></div></div>";149 150 $(msg_div).appendTo("body");151 var _this = this;152 setTimeout(function () {153 var d = 0.5;154 var m = document.getElementById("div_msg"+sid);155 m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';156 m.style.opacity = '0';157 setTimeout(_this.RemoveNode(m), 500);158 }, 500);159 },160 RemoveNode: function (m) {161 m.parentNode.removeChild(m);162 },163 // @param {string} img 图片的base64164 // @param {int} dir exif获取的方向信息165 // @param {function} next 回调方法,返回校正方向后的base64166 getImgData: function (e,img, dir, next) {167 var _this = this;168 var image = new Image();169 image.src = e.target.result;170 image.onload=function(){171 var degree=0,drawWidth,drawHeight,width,height;172 drawWidth=this.naturalWidth;173 drawHeight=this.naturalHeight;174 //以下改变一下图片大小175 var maxSide = Math.max(drawWidth, drawHeight);176 if (maxSide > 1024) {177 var minSide = Math.min(drawWidth, drawHeight);178 minSide = minSide / maxSide * 1024;179 maxSide = 1024;180 if (drawWidth > drawHeight) {181 drawWidth = maxSide;182 drawHeight = minSide;183 } else {184 drawWidth = minSide;185 drawHeight = maxSide;186 }187 }188 var canvas=document.createElement('canvas');189 canvas.width=width=drawWidth;190 canvas.height=height=drawHeight; 191 var context = canvas.getContext('2d');192 //判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式193 switch(dir){194 case 2:195 context.translate(width, 0);196 context.scale(-1, 1);197 break;198 case 3:199 context.translate(width, height);200 context.rotate(Math.PI);201 break;202 case 4:203 context.translate(0, height);204 context.scale(1, -1);205 break;206 case 5:207 context.rotate(0.5 * Math.PI);208 context.scale(1, -1);209 break;210 case 6:211 context.rotate(0.5 * Math.PI);212 context.translate(0, -height);213 break;214 case 7:215 context.rotate(0.5 * Math.PI);216 context.translate(width, -height);217 context.scale(-1, 1);218 break;219 case 8:220 context.rotate(-0.5 * Math.PI);221 context.translate(-width, 0);222 break;223 224 }225 context.beginPath();226 context.drawImage(this,0,0,drawWidth,drawHeight);227 //返回校正图片228 next(canvas.toDataURL("image/jpeg",.8));229 }230 }231 232 }233 234 imgOperate.onload();235 window.imgOperate = imgOperate;236 237 238 239 })();
View Code
在解决了上面问题后又发现了一些型号的手机图片竟然无法上传,我将它们的图片转到电脑上来测试,发现原因是它们的图片太大,已经超过了默认的4M。为此,我修改了一下配置,解决了相关的问题,配置修改如下:
1 <location path="图片代理服务器地址">2 <system.web>3 <httpRuntime maxRequestLength="10240"/>4 </system.web>5 </location>
使用location可以仅让上传图片的页面增加参数最大可传的值,而不会影响其它正常的页面。
原标题:大朋展翅 html5上传图片(三)一解决部分手机拍相册批量上传图片转向问题
关键词:HTML