在经过前面的改进之后本来以为已经没有问题了,但经过我们神通广大的测试的测试,发现相册中的图片在上传时也会发生转向问题。既然前面都解决了拍照转向的问题,那么相册中图片的上传也容易解决。修改一下需要旋转图片的类型判定即可,修改如下:
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: false 120 }).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="" + imgsrc + "" housepicid="">"; 128 } else { 129 dd.innerHTML = "<a class="close"></a><img src="" + 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 图片的base64 164 // @param {int} dir exif获取的方向信息 165 // @param {function} next 回调方法,返回校正方向后的base64 166 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 })();
在解决了上面问题后又发现了一些型号的手机图片竟然无法上传,我将它们的图片转到电脑上来测试,发现原因是它们的图片太大,已经超过了默认的4M。为此,我修改了一下配置,解决了相关的问题,配置修改如下:
1 <location path="图片代理服务器地址"> 2 <system.web> 3 <httpRuntime maxRequestLength="10240"/> 4 </system.web> 5 </location>
使用location可以仅让上传图片的页面增加参数最大可传的值,而不会影响其它正常的页面。