你的位置:首页 > Java教程

[Java教程]大朋展翅 html5上传图片(三)一解决部分手机拍相册批量上传图片转向问题


        在经过前面的改进之后本来以为已经没有问题了,但经过我们神通广大的测试的测试,发现相册中的图片在上传时也会发生转向问题。既然前面都解决了拍照转向的问题,那么相册中图片的上传也容易解决。修改一下需要旋转图片的类型判定即可,修改如下:

 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=\"" + 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 图片的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可以仅让上传图片的页面增加参数最大可传的值,而不会影响其它正常的页面。