WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。 采用大文件分片并发上传,极大的提高了文件上传效率。
1、引用脚本及样式
1 <!--引入CSS--> 2 <link rel="stylesheet" type="text/css" href="webuploader文件夹/webuploader.css"> 3 4 <!--引入JS--> 5 <script type="text/javascript" src="webuploader文件夹/webuploader.js"></script> 6 <!--引入JS--> 7 <script type="text/javascript" src="js2/jquery-1.10.2.min.js"></script> 8 <!--引入初始化JS及图片上传到文件服务器--> 9 <script type="text/javascript" src="js2/getting-starteder.js"></script>
getting-starteder.js--图片初始化及处理上传到服务器全是靠这个JS来实现
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 // 图片上传demo 2 jQuery(function() { 3 var $ = jQuery, 4 $list = $('#fileList'), 5 // 优化retina, 在retina下这个值是2 6 ratio = window.devicePixelRatio || 1, 7 8 // 缩略图大小 9 thumbnailWidth = 100 * ratio, 10 thumbnailHeight = 100 * ratio, 11 12 // Web Uploader实例 13 uploader; 14 15 // 初始化Web Uploader 16 uploader = WebUploader.create({ 17 18 // 自动上传。 19 auto: true, 20 21 // swf文件路径 22 swf: BASE_URL + '/js2/Uploader.swf', 23 24 // 文件接收服务端。 25 // server: 'http://webuploader.duapp.com/server/fileupload.php', 26 server: 'Handler/UploadHandleringNew.ashx', 27 28 // 选择文件的按钮。可选。 29 // 内部根据当前运行是创建,可能是input元素,也可能是flash. 30 pick: '#filePicker', 31 32 // 只允许选择文件,可选。 33 accept: { 34 title: 'Images', 35 extensions: 'gif,jpg,jpeg,bmp,png', 36 mimeTypes: 'image/*' 37 } 38 }); 39 40 // 当有文件添加进来的时候 41 uploader.on( 'fileQueued', function( file ) { 42 var $li = $( 43 '<div id="' + file.id + '" class="file-item thumbnail">' + 44 '<img>' + 45 '<div class="info">' + file.name + '</div>' + 46 '</div>' 47 ), 48 $img = $li.find('img'); 49 50 $list.append( $li ); 51 52 // 创建缩略图 53 uploader.makeThumb( file, function( error, src ) { 54 if ( error ) { 55 $img.replaceWith('<span>不能预览</span>'); 56 return; 57 } 58 59 $img.attr( 'src', src ); 60 }, thumbnailWidth, thumbnailHeight ); 61 }); 62 63 // 文件上传过程中创建进度条实时显示。 64 uploader.on( 'uploadProgress', function( file, percentage ) { 65 var $li = $( '#'+file.id ), 66 $percent = $li.find('.progress span'); 67 68 // 避免重复创建 69 if ( !$percent.length ) { 70 $percent = $('<p class="progress"><span></span></p>') 71 .appendTo( $li ) 72 .find('span'); 73 } 74 75 $percent.css( 'width', percentage * 100 + '%' ); 76 }); 77 78 // 文件上传成功,给item添加成功class, 用样式标记上传成功。 79 uploader.on( 'uploadSuccess', function( file ) { 80 $( '#'+file.id ).addClass('upload-state-done'); 81 }); 82 83 // 文件上传失败,现实上传出错。 84 uploader.on( 'uploadError', function( file ) { 85 var $li = $( '#'+file.id ), 86 $error = $li.find('div.error'); 87 88 // 避免重复创建 89 if ( !$error.length ) { 90 $error = $('<div class="error"></div>').appendTo( $li ); 91 } 92 93 $error.text('上传失败'); 94 }); 95 96 // 完成上传完了,成功或者失败,先删除进度条。 97 uploader.on( 'uploadComplete', function( file ) { 98 $('#' + file.id).find('.progress').remove(); 99 //alert('上传成功'); 100 }); 101 });
2、页面上代码:
<!--dom结构部分--> <div id="uploader-demo"> <!--用来存放item--> <div id="fileList" class="uploader-list"></div> <div id="filePicker">选择图片</div> </div>
我用是NET+ashx
上传后,由于WebUploader后,缩略图的正常,而上传服务器后,横拍的图片显示
如下图:
--上传到服务器后
解决方案:
在上传到服务器之前对图片进行强制转换方向,服务端把 jpeg 的图片纠正一下
根据照片的Exif信息修正
1 public static void RotateImage(Image img) 2 { 3 PropertyItem[] exif = img.PropertyItems; 4 byte orientation = 0; 5 foreach (PropertyItem i in exif) 6 { 7 if (i.Id == 274) 8 { 9 orientation = i.Value[0]; 10 i.Value[0] = 1; 11 img.SetPropertyItem(i); 12 } 13 } 14 15 switch (orientation) 16 { 17 case 2: 18 img.RotateFlip(RotateFlipType.RotateNoneFlipX); 19 break; 20 case 3: 21 img.RotateFlip(RotateFlipType.Rotate180FlipNone); 22 break; 23 case 4: 24 img.RotateFlip(RotateFlipType.RotateNoneFlipY); 25 break; 26 case 5: 27 img.RotateFlip(RotateFlipType.Rotate90FlipX); 28 break; 29 case 6: 30 img.RotateFlip(RotateFlipType.Rotate90FlipNone); 31 break; 32 case 7: 33 img.RotateFlip(RotateFlipType.Rotate270FlipX); 34 break; 35 case 8: 36 img.RotateFlip(RotateFlipType.Rotate270FlipNone); 37 break; 38 default: 39 break; 40 } 41 foreach (PropertyItem i in exif) 42 { 43 if (i.Id == 40962) 44 { 45 i.Value = BitConverter.GetBytes(img.Width); 46 } 47 else if (i.Id == 40963) 48 { 49 i.Value = BitConverter.GetBytes(img.Height); 50 } 51 } 52 }
这样就可以完美解决!!!
Exif specification 对图片方向说明
关于Exif Orientation标志的定义 http://sylvana.net/jpegcrop/exif_orientation.html
UploadHandleringNew.ashx
Value | 0th Row | 0th Column |
1 | top | left side |
2 | top | right side |
3 | bottom | right side |
4 | bottom | left side |
5 | left side | top |
6 | right side | top |
7 | right side | bottom |
8 | left side | bottom |
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <%@ WebHandler Language="C#" Class="UploadHandleringNew" %> 2 3 using System; 4 using System.Data; 5 using System.Configuration; 6 using System.Collections; 7 using System.Web; 8 using System.IO; 9 using System.Web.Security; 10 using System.Web.UI; 11 using System.Web.UI.WebControls; 12 using System.Web.UI.WebControls.WebParts; 13 using System.Web.UI.HtmlControls; 14 using ysw.BLL; 15 using ysw.Models; 16 using System.Drawing; 17 18 public class UploadHandleringNew : IHttpHandler, System.Web.SessionState.IRequiresSessionState 19 { 20 public string camera = String.Empty;//机型 21 public string focalLength = String.Empty;//焦距 22 public string shutterSpeed = String.Empty;//速度 23 public string aperture = String.Empty;//光圈 24 public string iso = String.Empty;//感光度 25 public string treePath = System.Web.HttpContext.Current.Server.MapPath("~/"); 26 public void ProcessRequest(HttpContext context) 27 { 28 context.Response.ContentType = "text/plain"; 29 context.Response.Charset = "utf-8"; 30 context.Response.ContentEncoding = System.Text.Encoding.UTF8; 31 System.Collections.Generic.IList<TempImages> list = new System.Collections.Generic.List<TempImages>(); 32 if (context.Session["TempImageList"] != null) 33 { 34 list = context.Session["TempImageList"] as System.Collections.Generic.IList<TempImages>; 35 } 36 37 if (list.Count >= 6) 38 { 39 context.Response.Write("上传数量已经超出系统限制的6个文件"); 40 return; 41 42 43 } 44 else 45 { 46 HttpPostedFile file = context.Request.Files[0]; 47 string uploadPath = HttpContext.Current.Server.MapPath(@context.Request["folder"]) + "\\"; 48 49 if (file != null) 50 { 51 if (!System.IO.Directory.Exists(uploadPath)) 52 { 53 System.IO.Directory.CreateDirectory(uploadPath); 54 } 55 Random random = new Random(); 56 string fileName = DateTime.Now.ToString("yyyy-MM-dd") + "-" + random.Next(999999999) + file.FileName.Substring(file.FileName.Length - 4); // 文件名称 57 string fileName_s = "x_" + fileName; // 缩略图文件名称 58 string fileName_syp = "water_" + fileName; // 水印图文件名称(图片) 59 string webFilePath = ""; 60 string webFilePath_s = ""; 61 string webFilePath_s1 = ""; 62 string webFilePath_syp = ""; 63 webFilePath = treePath + @"originalImages\" + fileName; // 服务器端文件路径 64 webFilePath_s = treePath + @"thumbnails\" + fileName_s; // 服务器端缩略图路径 65 webFilePath_syp = treePath + @"waterImages\" + fileName_syp; // 服务器端带水印图路径(图片) 66 webFilePath_s1 = treePath + @"thumbnails166\" + fileName_s; // 服务器端缩略图路径 67 string webFilePath_sypf = System.Web.HttpContext.Current.Server.MapPath(@"~/images/synew.png"); // 服务器端水印图路径(图片) 68 file.SaveAs(webFilePath); 69 70 71 72 73 AddWaterPic(webFilePath, webFilePath_syp, webFilePath_sypf);//生成图片水印图 74 75 int towidth = 0; 76 int toheight = 0; 77 //MakeImage1(webFilePath, webFilePath_syp, 500); 78 MakeImage(webFilePath, webFilePath_s, 235); 79 //将临时数据保存到临时表中 80 TempImages tempImage = new TempImages(); 81 tempImage.ISBN = fileName; 82 if (context.Session["UserInfo"] != null) 83 { 84 tempImage.UserId = (context.Session["UserInfo"] as ysw.Model.UserInfo).Id; 85 } 86 else 87 { 88 tempImage.UserId = 2; 89 } 90 91 tempImage.CreateTime = DateTime.Now; 92 tempImage.Id = TempImageManager.AddTempImages(tempImage); 93 if (tempImage.Id > 0) 94 { 95 list.Add(tempImage); 96 context.Session["TempImageList"] = list; 97 string str = "waterImages/" + fileName_syp + ",thumbnails/" + fileName_s + "," + camera + "," + focalLength + "," + shutterSpeed + "," + aperture + "," + iso; 98 //上传成功后让上传队列的显示自动消失 99 //string str = fileName + ","; 100 //int toheight1 = 90; 101 // int towidth1 = 90; 102 // if ((double)towidth >(double)toheight) 103 // { 104 // toheight1 = toheight * 90 / towidth; 105 // } 106 // else 107 // { 108 // towidth1 = towidth * 90 / toheight; 109 // } 110 // str += towidth1 + "," + toheight1; 111 context.Response.Write(str); 112 } 113 else 114 { 115 context.Response.Write("0"); 116 } 117 } 118 else 119 { 120 context.Response.Write("0"); 121 } 122 } 123 } 124 public static void rotating(string Path_syp) 125 { 126 System.Drawing.Image img = System.Drawing.Image.FromFile(Path_syp); 127 128 System.Drawing.Imaging.PropertyItem[] exif = img.PropertyItems; 129 byte orientation = 0; 130 foreach (System.Drawing.Imaging.PropertyItem i in exif) 131 { 132 if (i.Id == 274) 133 { 134 orientation = i.Value[0]; 135 i.Value[0] = 1; 136 img.SetPropertyItem(i); 137 } 138 } 139 140 switch (orientation) 141 { 142 case 2: 143 img.RotateFlip(RotateFlipType.RotateNoneFlipX); 144 break; 145 case 3: 146 img.RotateFlip(RotateFlipType.Rotate180FlipNone); 147 break; 148 case 4: 149 img.RotateFlip(RotateFlipType.RotateNoneFlipY); 150 break; 151 case 5: 152 img.RotateFlip(RotateFlipType.Rotate90FlipX); 153 break; 154 case 6: 155 img.RotateFlip(RotateFlipType.Rotate90FlipNone); 156 break; 157 case 7: 158 img.RotateFlip(RotateFlipType.Rotate270FlipX); 159 break; 160 case 8: 161 img.RotateFlip(RotateFlipType.Rotate270FlipNone); 162 break; 163 default: 164 break; 165 166 } 167 foreach (System.Drawing.Imaging.PropertyItem i in exif) 168 { 169 if (i.Id == 40962) 170 { 171 i.Value = BitConverter.GetBytes(img.Width); 172 } 173 else if (i.Id == 40963) 174 { 175 i.Value = BitConverter.GetBytes(img.Height); 176 } 177 } 178 179 180 //System.Drawing.Image bitmap = new System.Drawing.Bitmap(500, 500); 181 182 //System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap); 183 184 185 // //以jpg格式保存缩略图 186 // bitmap.Save(Path_syp, System.Drawing.Imaging.ImageFormat.Jpeg); 187 188 // //image.Dispose(); 189 // bitmap.Dispose(); 190 // g.Dispose(); 191 192 } 193 /// <summary> 194 /// 生成缩略图方法(700px图片) 195 /// </summary> 196 /// <param name="webFilePath"></param> 197 /// <param name="webFilePath_s"></param> 198 /// <param name="size"></param> 199 private static void MakeImage1(string webFilePath, string webFilePath_s, int size) 200 { 201 System.Drawing.Image image = System.Drawing.Image.FromFile(webFilePath); 202 int towidth = size; 203 int toheight = size; 204 int x = 0; 205 int y = 0; 206 int ow = image.Width; 207 int oh = image.Height; 208 toheight = image.Height * size / image.Width; 209 System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight); //新建一个画板 210 System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap); //设置高质量插值法 211 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; //设置高质量,低速度呈现平滑程度 212 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; //清空画布并以透明背景色填充 213 g.Clear(System.Drawing.Color.Transparent); //在指定位置并且按指定大小绘制原图片的指定部分 214 g.DrawImage(image, new System.Drawing.Rectangle(0, 0, towidth, toheight), new System.Drawing.Rectangle(x, y, ow, oh), System.Drawing.GraphicsUnit.Pixel); 215 g.Dispose(); 216 bitmap.Save(webFilePath_s, System.Drawing.Imaging.ImageFormat.Jpeg); 217 image.Dispose(); 218 } 219 /// <summary> 220 /// 生成缩略图 221 /// </summary> 222 /// <param name="webFilePath">原图的路径</param> 223 /// <param name="webFilePath_s">缩略图的路径</param> 224 /// <param name="size">缩略图的大小</param> 225 public static void MakeImage(string webFilePath, string webFilePath_s, int size) 226 { 227 System.Drawing.Image image = System.Drawing.Image.FromFile(webFilePath); 228 int towidth = size; 229 int toheight = size; 230 int x = 0; 231 int y = 0; 232 int ow = image.Width; 233 int oh = image.Height; 234 235 if ((double)image.Width / (double)image.Height > (double)towidth / (double)toheight) 236 { 237 oh = image.Height; 238 ow = image.Height * towidth / toheight; 239 y = 0; 240 x = 0; 241 } 242 else 243 { 244 ow = image.Width; 245 oh = image.Width * toheight / towidth; 246 x = 0; 247 y = 0; 248 } 249 System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight); //新建一个画板 250 System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap); //设置高质量插值法 251 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; //设置高质量,低速度呈现平滑程度 252 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; //清空画布并以透明背景色填充 253 g.Clear(System.Drawing.Color.Transparent); //在指定位置并且按指定大小绘制原图片的指定部分 254 g.DrawImage(image, new System.Drawing.Rectangle(0, 0, towidth, toheight), new System.Drawing.Rectangle(x, y, ow, oh), System.Drawing.GraphicsUnit.Pixel); 255 try 256 { 257 //以jpg格式保存缩略图 258 bitmap.Save(webFilePath_s, System.Drawing.Imaging.ImageFormat.Jpeg); 259 } 260 catch (System.Exception e) 261 { 262 throw e; 263 } 264 finally 265 { 266 image.Dispose(); 267 bitmap.Dispose(); 268 g.Dispose(); 269 } 270 } 271 /// <summary> 272 /// 生成水印缩略图 273 /// </summary> 274 /// <param name="Path"></param> 275 /// <param name="Path_syp"></param> 276 /// <param name="Path_sypf"></param> 277 protected void AddWaterPic(string Path, string Path_syp, string Path_sypf) 278 { 279 System.Drawing.Image image = System.Drawing.Image.FromFile(Path); 280 System.Drawing.Image copyImage = System.Drawing.Image.FromFile(Path_sypf); 281 282 283 284 285 286 287 System.Drawing.Imaging.PropertyItem[] exif = image.PropertyItems; 288 byte orientation = 0; 289 foreach (System.Drawing.Imaging.PropertyItem i in exif) 290 { 291 if (i.Id == 274) 292 { 293 orientation = i.Value[0]; 294 i.Value[0] = 1; 295 image.SetPropertyItem(i); 296 } 297 } 298 299 switch (orientation) 300 { 301 case 2: 302 image.RotateFlip(RotateFlipType.RotateNoneFlipX); 303 break; 304 case 3: 305 image.RotateFlip(RotateFlipType.Rotate180FlipNone); 306 break; 307 case 4: 308 image.RotateFlip(RotateFlipType.RotateNoneFlipY); 309 break; 310 case 5: 311 image.RotateFlip(RotateFlipType.Rotate90FlipX); 312 break; 313 case 6: 314 image.RotateFlip(RotateFlipType.Rotate90FlipNone); 315 break; 316 case 7: 317 image.RotateFlip(RotateFlipType.Rotate270FlipX); 318 break; 319 case 8: 320 image.RotateFlip(RotateFlipType.Rotate270FlipNone); 321 break; 322 default: 323 break; 324 325 } 326 foreach (System.Drawing.Imaging.PropertyItem i in exif) 327 { 328 if (i.Id == 40962) 329 { 330 i.Value = BitConverter.GetBytes(image.Width); 331 } 332 else if (i.Id == 40963) 333 { 334 i.Value = BitConverter.GetBytes(image.Height); 335 } 336 } 337 338 339 340 341 342 int towidth = 500; 343 int toheight = 500; 344 int x = 0; 345 int y = 0; 346 int ow = image.Width; 347 int oh = image.Height; 348 if (image.Width < 500 ) 349 { 350 toheight = image.Height; 351 towidth = image.Width; 352 } 353 else 354 { 355 towidth = 500; 356 toheight = image.Height * 500 / image.Width; 357 358 } 359 //rotating(Path); 360 361 System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight); 362 System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap); 363 364 g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; //设置高质量,低速度呈现平滑程度 365 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; //清空画布并以透明背景色填充 366 g.Clear(System.Drawing.Color.Transparent); //在指定位置并且按指定大小绘制原图片的指定部分 367 g.DrawImage(image, new System.Drawing.Rectangle(0, 0, towidth, toheight), new System.Drawing.Rectangle(x, y, ow, oh), System.Drawing.GraphicsUnit.Pixel); 368 369 g.DrawImage(copyImage, new System.Drawing.Rectangle(bitmap.Width - 10 - copyImage.Width, bitmap.Height - 8 - copyImage.Height, copyImage.Width, copyImage.Height), 0, 0, copyImage.Width, copyImage.Height, System.Drawing.GraphicsUnit.Pixel); 370 g.Dispose(); 371 372 bitmap.Save(Path_syp); 373 image.Dispose(); 374 } 375 public bool IsReusable { 376 get { 377 return false; 378 } 379 } 380 381 }