图片选择,预览及上传

记得以前老师教我们写项目,要实现图片上传的功能,我们都是先用一个input选好图片,然后单独做一个提交图片的按钮,点击按钮,使用form表单提交到后台,然后通过

// 获取上传的文件
HttpPostedFileBase file = Request.Files[0];

这一行来获取上传到后台的文件,然后来验证上传的文件是不是图片,其实在前台,通过设置input属性,就可以限制我们只能选择图片文件了,当然,后台的验证也是不能少的,

// 设置accept属性,限制能选择的文件类型为图片
<input type="file" accept="image/*" id="upload" />

当我们在前台提交图片到后台,并且,在后台获取到之后,下一步,我们要做的就是上传图片了,代码如下

 1     // 以'.'、'..'、'~'开头的路径,均为相对路径(推荐使用)
 2     // 以盘符'C:'、'D:',等开头的,均为绝对路径
 3     // 上传路径,可以任意修改
 4     string path = "~/upload";
 5 
 6     // 获取上传的文件名(包含后缀)
 7     string FileName = file.FileName;
 8 
 9     // 获取上传绝对路径,若path初始值就是绝对路径,可以忽略不写
10     path = Server.MapPath(path);
11 
12     // 检测是否存在此路径,没有就创建
13     // 需引用命名空间,using System.IO;
14     if (!Directory.Exists(path))    
15         // 创建路径
16         Directory.CreateDirectory(path);
17 
18     // 上传文件
19     file.SaveAs(path + FileName);

 

其实写到这里图片上传就已经成功了,但是,凡事都会有个但是!!

原生的input选择图片之后,只能显示一个文件名吧,如果我们想选择图片之后,立刻能够看到我们选择的图片,那么问题就来了,怎么办???

曾经做过一次这种效果,当然,灰常麻烦,早就不用了,不过大概的思路还是讲讲吧

  1. 给input加一个onchange事件,每次选择的文件修改之后就会触发
  2. 在onchange事件中添加一个方法(Uoplad),这个方法要执行的功能就是提交input所在的form表单
  3. 提交form表单后,在后台将提交上来的图片文件保存在指定位置(path)
  4. 这时候path位置肯定有那张图片,在方法Upload中,我们就可以直接取path位置拿图片,更新一下指定img的src属性就好

这样写是可以实现图片选择之后,立刻显示的效果的,操作麻烦不说,问题也有很多,如果我们一直挑选图片,那些被我们挑过但是不用的图片都会被上传,大量的垃圾数据就这样产生了,而且,反复提交form表单,对网站的负担也会比较大的,都说度娘是万能的,果不其然,找了很久之后,终于被我找到了一个非常不错的方法

前端js方法:

 1    // 选择图片预览方法
 2    // ImgID,显示预览图片的img标签id
 3    // FileInputID,选择文件的input标签id
 4    // MaxLengt,能选择的最大文件大小(单位:mb),默认2M,可以忽略不填
 5     function ChangImg(ImgID, FileInputID, MaxLength = 2.0) {
 6 
 7         // 触发Input单击事件
 8         $("#" + FileInputID).click();
 9 
10         // Input单击执行
11         $("#" + FileInputID).on("change", function () {
12 
13             //设置上传的文件最大值(单位:M),超过此值则不上传。
14             var flength = MaxLength;
15             var size = this.files[0].size;
16 
17             size = (size / 1024 / 1024).toFixed(2);
18 
19             // 判断是否超过最大大小
20             if (size > MaxLength) {
21                 alert("所选文件大小:" + size + " M,最大文件大小:" + MaxLength + " M");
22 
23                 // 清空Fileinput的值
24                 if (this.outerHTML)
25                     this.outerHTML = this.outerHTML;
26                 else
27                     this.values = "";
28 
29                 // 显示默认图片
30                 $("#" + ImgID).attr("src", '/upload/Click.png');
31                 return;
32             }
33 
34             // 获取图片的路径,该路径不是图片在本地的路径
35             var objUrl = null;
36 
37             // 为文件创建一个Url对象,可能会有一点点兼容性问题
38             objUrl = window.URL.createObjectURL(this.files[0]);
39 
40             if (objUrl)
41                 // 将图片路径存入src中,显示出图片
42                 $("#" + ImgID).prop("src", objUrl);
43 
44         });
45     }

感谢那位不知名的大神,我在他的基础上进行了修改,添加了文件大小验证,因为默认只能上传两兆还是四兆的文件来着,不记得了,反正不大,如果你没有修改默认配置,而你选择的文件又偏偏超过了这个范围,提交form表单的时候绝对会炸的你不要不要的,,,

至于这个方法怎么用,我也大概的写了一套模板,跟着模板来肯定是没问题的

前端HTML代码:

 1    <!-- 
 2          必须添加 enctype = "multipart/form-data" 属性,否则后台无法接收到上传的文件!!
 3          我是基于MVC实现的,其他的其实也一样,略微修改就好
 4          嗯,我也没有加CSS,你们随意加,,
 5          -->
 6     <form action="/Home/Upload"  enctype = "multipart/form-data">
 7         <p>
 8             <label>选择图片:</label>
 9             <label>
10                 <!-- 预览的图片,单击它就可以选择图片 -->
11                 <img src="~/images/Click.png" id="pic" title="单击选择图片" onclick="ChangImg('pic','upload')" />
12                 <!-- 单击图片,其实触发的是它的单击事件,将其隐藏起来更美观 -->
13                 <input type="file" accept="image/*" id="upload" style="display:none;" />
14             </label>
15         </p>
16         <!-- 单击按钮,即可开始上传 -->
17         <p> <input type="submit" value="开始上传" /></p>
18     </form>

后台代码:

  1         // 
  2         public ActionResult Upload(){
  3             // 参数看着给,所有的参数都有默认值,都可以修改成自己常用的值
  4             string fileUrl = SaveFile();
  5 
  6             // 若要获取多文件上传的值,使用splitChar参数的值进行分割就好,默认splitChar=';',即
  7             // string[] res=fileUrl.Split(';');
  8 
  9             // 判断fileUrl是否为空,若为空,表示没有上传文件
 10             if(string.IsNullOrEmpty(fileUrl))
 11                 return Content("上传失败!");
 12             // 不为空时,上传成功
 13             else
 14                 return Content("上传成功!");
 15         }        
 16 
 17 
 18         #region 图片上传,此方法可以通用
 19         
 20         /// <summary>
 21         /// 上传图片
 22         /// </summary>
 23         /// <param name="type">存储方式,默认按年份分类</param>
 24         /// <param name="path">上传路径,默认值可以更改为自己常用的地址</param>
 25         /// <param name="IsUrl">是否返回路径,若不返回路径,就返回文件名称</param>
 26         /// <param name="format">文件名格式</param>
 27         /// <param name="splitChar">多文件路径分割符</param>
 28         /// <returns>默认返回图片上传的相对路径,IsUrl为false时,返回图片名称</returns>
 29         public string SaveFile(SaveType type = SaveType.ForYear, string path = "~/upload/",bool IsUrl=true, string format = "yyyyMMddHHmmssffff", char splitChar = ';') {
 30             // 返回所有的上传路径,以splitChar分割
 31             string resUrl = "";
 32             // 图片格式数组
 33             string[] imgFormat = { ".bmp", ".gif", ".png", ".jpg", ".jpeg" };
 34 
 35             // 循环所有的上传文件
 36             for (int i = 0; i < Request.Files.Count; i++) {
 37 
 38                 // 上传图片
 39                 HttpPostedFileBase file = Request.Files[i];
 40                 string FileName = file.FileName; // 上传的原文件名
 41 
 42                 if (FileName.Length > 0) {
 43 
 44                     // 获取文件后缀名
 45                     string Suffix = FileName.Substring(FileName.LastIndexOf('.'));
 46 
 47                     // 判断文件是否为图片,若不是图片,跳出,检测下一个文件
 48                     if (Array.IndexOf(imgFormat, Suffix) == -1)
 49                         continue;
 50 
 51                     // 拼接文件名称
 52                     DateTime dateNow = DateTime.Now;
 53                     FileName = dateNow.ToString(format) + Suffix;
 54 
 55                     // 根据存储方式,修改路径
 56                     // 增加年份文件夹
 57                     if (Convert.ToInt32(type) >= 1)
 58                         path += dateNow.Year + "/";
 59                     // 增加月份文件夹
 60                     if (Convert.ToInt32(type) >= 2)
 61                         path += dateNow.Month + "/";
 62                     // 增加天数文件夹
 63                     if (Convert.ToInt32(type) >= 3)
 64                         path += dateNow.Day + "/";
 65 
 66                     // 若有多个文件要上传,将它们一一进行拼接
 67                     if (!string.IsNullOrEmpty(resUrl))
 68                         resUrl += splitChar;
 69     
 70                     // 若返回相对路径(默认)
 71                     if(IsUrl)
 72                         // .Substring(1),用于去掉第一个字符'~',可视情况修改或去掉
 73                         resUrl += (path + FileName).Substring(1);
 74                     // 若返回文件名称
 75                     else
 76                         resUrl += FileName;
 77 
 78                     // 获取上传绝对路径
 79                     path = Server.MapPath(path);
 80 
 81                     // 检测是否存在此路径,没有就创建
 82                     if (!Directory.Exists(path))
 83                         // 创建路径
 84                         Directory.CreateDirectory(path);
 85 
 86                     // 上传图片
 87                     file.SaveAs(path + FileName);
 88                 }
 89             }
 90             return resUrl;
 91         }
 92 
 93         /// <summary>
 94         /// 文件存储方式,枚举
 95         /// </summary>
 96         public enum SaveType {
 97             /// <summary>
 98             /// 直接上传至指定目录
 99             /// </summary>
100             ForNone = 0,
101             /// <summary>
102             /// 按年份区分上传,每一年的图片在同一个文件夹
103             /// </summary>
104             ForYear = 1,
105             /// <summary>
106             /// 按月份区分上传,每个月的图片在同一个文件夹
107             /// </summary>
108             ForMonth = 2,
109             /// <summary>
110             /// 按天份区分上传,每一天的图片在同一个文件夹
111             /// </summary>
112             ForDay = 3
113         }
114         #endregion

嗯,到这就差不多,能耐心读到这里的都是一个好读者啊,嘿嘿,谢啦,希望能对你们有所帮助,,,

posted @ 2017-07-29 17:49  步尘  阅读(1233)  评论(0编辑  收藏  举报