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("\r\n--" + boundary + "\r\n");
52                 byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
53               
54                 //請求頭部信息 
55                 StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n",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 字符、兩個以上的填充字"。經過反復的調整,終於實現了相應的功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM