html5上传图片(二)一解决部分手机拍照上传图片转向问题

       本以为解决跨域上传后没有问题了,不成想被测试找出一个问题,那就是在手机上拍照上传后图片会旋转。很头痛,不过没有办法,问题还是需要解决的。在查阅了一系列资料后我找到了相应的解决方案,利用exif.js获取图片旋转的方向,然后再转过来图片,之后再上传。这个方案需要修改前面的脚本,同样的,由于要传base64字符串,后台也要做出相应的修改。下面是我修改后的相应代码:

  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                
 23                 _this.uploadFiles(this);
 24               
 25             });
 26     
 27         },
 28         InserImage:function(urls,dd)
 29         {
 30             $.post(this.operateUrl, { houseid: houseid, operateType: 1, picStr: urls }, function (data) {
 31                 data = eval("(" + data + ")");
 32                 if (data && data.picIds)
 33                 {
 34                     dd.getElementsByTagName("img")[0].setAttribute("housepicid", data.picIds);
 35                 }
 36             });
 37         },
 38         uploadFiles: function (where) {
 39             if (!houseid) { 
 40                 this.ShowMsg("请回到第一步完善相应的信息");
 41                 return;
 42             }
 43             var imgLength = $("#entrust dd").length - 1;
 44             
 45             if (imgLength >= 50)
 46             {
 47                 this.ShowMsg("你的图片超过了50张,不能再上传");
 48                 return;
 49             }
 50             if (imgLength + where.files.length > 50)
 51             {
 52                 this.ShowMsg("你选择的图片超过了50张,无法上传,请重新选择");
 53                 return;
 54             }
 55          
 56 
 57             var _this = this;
 58             var radtime = new Date();
 59             var sid = radtime.getTime();
 60             this.successCount=0;
 61             for (var i = 0; i < where.files.length; i++) {
 62                 var formData = new FormData();
 63                 var file = where.files[i];
 64                 var orientation = 1;
 65       
 66                 if (file.name.indexOf("jpg") > -1) {
 67                     EXIF.getData(file, function () {
 68                         EXIF.getAllTags(this);  
 69                         orientation = EXIF.getTag(this, 'Orientation');
 70                         if (orientation) {
 71                             var reader = new FileReader();
 72                             reader.onload = function (e) {
 73                                 _this.getImgData(e, this.result, orientation, function (data) {
 74 
 75                                     var base64String = data;
 76                                     formData.append("icoimage", base64String);
 77                                     _this.UploadImg(where, formData, sid, i);
 78                                 });
 79                             }
 80                             reader.readAsDataURL(file);
 81                         } else {
 82                             formData.append("icoimage", file);
 83                             _this.UploadImg(where, formData, sid, i);
 84                         }
 85                     });
 86                 } else {
 87                     formData.append("icoimage", file);
 88                     _this.UploadImg(where, formData, sid, i);
 89                 }
 90               
 91               
 92              
 93             }
 94 
 95         },
 96         UploadImg: function (where, formData, sid, i) {
 97             var _this = this;
 98             $.ajax({
 99                 url: this.uploadUrl + '?channel=频道&sid=' + sid,
100                 type: 'POST',
101                 cache: false,
102                 data: formData,
103                 processData: false,
104                 contentType: false
105             }).success(function (res) {
106                 var imgsrc = res;
107                 if (imgsrc == "-1" || imgsrc == "302" || imgsrc == -1 || imgsrc == 302) {
108                     _this.ShowMsg("上传失败,照片超过10M");
109                 } else if (imgsrc.indexOf("http") != -1) {
110                     var dd = document.createElement("dd");
111                     if ($("#entrust dd").length == 1) {
112                         dd.innerHTML = "<div class="cver">封面图</div><a class="close"></a><img src="" + imgsrc + "" housepicid="">";
113                     } else {
114                         dd.innerHTML = "<a class="close"></a><img src="" + imgsrc + "" housepicid="">";
115                     }
116                     document.getElementById("entrust").appendChild(dd);
117                     _this.dlWidth += _this.ddWidth + 17;
118                     $('#entrust').css("width", _this.dlWidth);
119                     _this.InserImage(imgsrc, dd);
120                     this.successCount++;
121                     _this.ShowMsg("正在上传第" + i + "张图片");
122                 }
123                 if (i == where.files.length) {
124                     if (this.successCount > 0) {
125                         _this.ShowMsg("成功上传" + successCount + ",可继续上传新照片");
126                     }
127                 } 
128 
129             })
130         },
131         ShowMsg: function (text, mymethod) {
132             var radtime = new Date();
133             var sid = radtime.getTime();
134             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>";
135 
136             $(msg_div).appendTo("body");
137             var _this = this;
138             setTimeout(function () {
139                 var d = 0.5;
140                 var m = document.getElementById("div_msg"+sid);
141                 m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
142                 m.style.opacity = '0';
143                 setTimeout(_this.RemoveNode(m), 500);
144             }, 500);
145         },
146         RemoveNode: function (m) {
147             m.parentNode.removeChild(m);
148         },
149         // @param {string} img 图片的base64
150         // @param {int} dir exif获取的方向信息
151         // @param {function} next 回调方法,返回校正方向后的base64
152         getImgData: function (e,img, dir, next) {
153             var _this = this;
154             var image = new Image();
155             image.src = e.target.result;
156     image.onload=function(){
157         var degree=0,drawWidth,drawHeight,width,height;
158         drawWidth=this.naturalWidth;
159         drawHeight=this.naturalHeight;
160         //以下改变一下图片大小
161         var maxSide = Math.max(drawWidth, drawHeight);
162         if (maxSide > 1024) {
163             var minSide = Math.min(drawWidth, drawHeight);
164             minSide = minSide / maxSide * 1024;
165             maxSide = 1024;
166             if (drawWidth > drawHeight) {
167                 drawWidth = maxSide;
168                 drawHeight = minSide;
169             } else {
170                 drawWidth = minSide;
171                 drawHeight = maxSide;
172             }
173         }
174         var canvas=document.createElement('canvas');
175         canvas.width=width=drawWidth;
176         canvas.height=height=drawHeight; 
177         var context = canvas.getContext('2d');
178         //判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式
179         switch(dir){
180             case 2:
181                 context.translate(width, 0);
182                 context.scale(-1, 1);
183                 break;
184             case 3:
185                 context.translate(width, height);
186                 context.rotate(Math.PI);
187                 break;
188             case 4:
189                 context.translate(0, height);
190                 context.scale(1, -1);
191                 break;
192             case 5:
193                 context.rotate(0.5 * Math.PI);
194                 context.scale(1, -1);
195                 break;
196             case 6:
197                 context.rotate(0.5 * Math.PI);
198                 context.translate(0, -height);
199                 break;
200             case 7:
201                 context.rotate(0.5 * Math.PI);
202                 context.translate(width, -height);
203                 context.scale(-1, 1);
204                 break;
205             case 8:
206                 context.rotate(-0.5 * Math.PI);
207                 context.translate(-width, 0);
208                 break;
209           
210         }
211 
212         context.drawImage(this,0,0,drawWidth,drawHeight);
213         //返回校正图片
214         next(canvas.toDataURL("image/jpeg",.8));
215     }
216     image.src=img;
217 }
218 
219     }
220 
221     imgOperate.onload();
222     window.imgOperate = imgOperate;
223 
224 })();
225    
前端脚本
 1   public override void ProcessRequest(HttpContext context)
 2         {
 3             //获取目标站点地址
 4             String target = "图片服务器地址";
 5             string sid = context.Request["sid"];
 6             target = string.Format("{0}?city=&channel=频道&sid={1}&backurl=",target,sid);
 7             string imgText = string.Empty;
 8             if (context.Request.Files.Count == 0 && string.IsNullOrEmpty(imgText=context.Request["icoimage"]))
 9             {
10                 Response.Write("0");
11                 Response.End();
12             }
13 
14             Stream stream = new MemoryStream();
15             string fileName = string.Empty;
16             byte[] bArr = null;
17             if (context.Request.Files.Count > 0)
18             {
19               var  file = context.Request.Files[0];
20               fileName = file.FileName;
21               stream = file.InputStream;
22               bArr = new byte[stream.Length];
23               stream.Read(bArr, 0, bArr.Length);
24               stream.Close();
25             }
26             else {
27                 imgText = HttpUtility.UrlDecode(imgText);
28                 imgText = Regex.Match(imgText, "(?<=,).*").Value;
29                    imgText= imgText.Trim().Replace("%", "").Replace(",", "").Replace(" ", "+");
30                    if (imgText.Length % 4 > 0)
31                    {
32                        imgText = imgText.PadRight(imgText.Length + 4 - imgText.Length % 4, '=');
33                    }
34               bArr=Convert.FromBase64String(imgText);
35             
36                  fileName = "base64.png";
37                
38             }
39                 HttpWebRequest request = WebRequest.Create(target) as HttpWebRequest;
40                 CookieContainer cookieContainer = new CookieContainer();
41                 request.CookieContainer = cookieContainer;
42                 request.AllowAutoRedirect = true;
43                 request.Method = "POST";
44                 request.Headers.Add("Origin", "http://" + context.Request.UrlReferrer.Host);
45                 request.Headers.Add("Accept-Encoding", "gzip, deflate");
46                 request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
47                 request.Headers.Add("Upgrade-Insecure-Requests", "1");
48                 request.Referer = context.Request.UrlReferrer.OriginalString;
49                 string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
50                 request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
51                 byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("
--" + boundary + "
");
52                 byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("
--" + boundary + "--
");
53               
54                 //请求头部信息 
55                 StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name="file";filename="{0}"
Content-Type:application/octet-stream

",fileName));
56                 byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());
57 
58                 Stream postStream = request.GetRequestStream();
59                 postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
60                 postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
61                 postStream.Write(bArr, 0, bArr.Length);
62                 postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
63                 postStream.Close();
64                 //发送请求并获取相应回应数据
65                 HttpWebResponse response = request.GetResponse() as HttpWebResponse;
66                 SetCookie(response,context);
67             
68         
69    
70         }
71 
72 
73       
74         //response是目标服务器的响应对象,context是返回给浏览器的上下文对象
75         void SetCookie(HttpWebResponse response, HttpContext context)
76         {
77             foreach (Cookie cookie in response.Cookies)
78             {
79                 if (cookie.Name!=null&&cookie.Name.StartsWith("Picture"))
80                 {
81                     string result=string.Empty;
82                     if (cookie.Value != null && cookie.Value.StartsWith("http://"))
83                     {
84                         Regex r = new Regex(@"^.*?(?=|)");
85                         result = r.Match(cookie.Value).Value;
86                     }
87                     else {
88                         result = cookie.Value;
89                     }
90                     context.Response.Write(result);
91                     context.Response.End();
92                 }
93             
94             }
95         }
View Code

      本次遇到的难题主要是解析base64字符串的问题,总是遇到"输入的不是有效的 Base-64 字符串,因为它包含非 Base-64 字符、两个以上的填充字"。经过反复的调整,终于实现了相应的功能。

原文地址:https://www.cnblogs.com/xietong/p/5741905.html