本代碼實現圖片文件上傳並生成縮略圖以及文件安全效驗等。
多文件上傳效果只兼容 IE10、firefox、chrome 等瀏覽器,其他瀏覽器只能單文件上傳。
事件:
開發代碼中一般使用傳統的FileUpload控件進行單個文件上傳,選擇圖片文件時又無法達到實時預覽的效果,而且無法實施對多件文件一次性上傳。
實現圖片預覽在第二篇中詳細描述,請關注。
代碼架構圖:
初步效果圖(火狐下):
實施邏輯:
1、主界面使用框架嵌套文件接收頁面,通過File控件選擇多個文件后,將文件Post提交至文件接收頁面。
2、接收頁面將傳入的文件圖片保存至站點臨時目錄,保存完成后讀取臨時目錄中的圖片進行預覽以及保存(預覽圖片為縮略圖)。
3、刪除操作:將選中的圖片及縮略圖從臨時目錄中刪除。
4、保存:將選中的圖片及縮略圖全部移動到站點指定圖片目錄。
5、取消上傳:刪除臨時目錄里的所有文件。
說明:
第2步驟中需同時生成圖片縮略圖以及效驗文件安全。
主要代碼模塊:
文件效驗模塊
5 /// <summary> 6 /// 效驗文件安全性 7 /// 將效驗文件正確格式,即使更改文件類型及擴展名也無法通過此效驗方法 8 /// </summary> 9 public static Result checkFile(string FilePath) 10 { 11 try 12 { 13 FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read); 14 BinaryReader r = new BinaryReader(fs); 15 string fileclass = ""; 16 byte buffer = r.ReadByte(); 17 fileclass = buffer.ToString(); 18 buffer = r.ReadByte(); 19 fileclass += buffer.ToString(); 20 r.Close(); 21 fs.Close(); 22 23 //文件類型錯誤,將刪除文件 24 bool falg = false; 25 string[] FileType = new string[] { "255216", "7173", "13780" }; 26 //數字說明,只針對目前主流圖片格式: 27 //255216 代表 .jpg文件 28 //13780 代表 .png文件 29 //7173 代表 .gif文件 30 foreach (string n in FileType) 31 { 32 if (fileclass == n) 33 { 34 falg = true; 35 break; 36 } 37 } 38 if (!falg) 39 { 40 File.Delete(FilePath); 41 return new Result(-1,"上傳文件為非法文件,請謹慎上傳。"); 42 } 43 return new Result(1,"true"); 44 } 45 catch (Exception ex) 46 { 47 throw ex; 48 } 49 }
圖片縮略圖生成模塊
5 /// <summary> 6 /// 生成圖片縮略圖 7 /// </summary> 8 /// <param name="filePath">圖片地址</param> 9 /// <param name="newFileName">縮略圖地址</param> 10 public static string CreateThumbnailImage(string filePath, string newFileName) 11 { 12 try 13 { 14 if (File.Exists(filePath)) 15 { 16 System.Drawing.Image copyImage = System.Drawing.Image.FromFile(filePath); 17 //為寫入縮略圖委托事件 18 System.Drawing.Image.GetThumbnailImageAbort callb = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback); 19 System.Drawing.Image ReducedImage = copyImage.GetThumbnailImage(ThumbnailImgWidth, ThumbnailImgHeigth, callb, IntPtr.Zero); //獲取縮略圖 20 //保存縮略圖 21 ReducedImage.Save(newFileName, System.Drawing.Imaging.ImageFormat.Jpeg); 22 ReducedImage.Dispose(); 23 copyImage.Dispose(); 24 return newFileName; 25 } 26 } 27 catch (Exception ex) 28 { 29 throw ex; 30 } 31 return string.Empty; 32 } 33 34 /// <summary> 35 /// 構造方法 為委托事件寫入縮略圖 36 /// </summary> 37 public static bool ThumbnailCallback() 38 { 39 return false; 40 }
獲取頁面post傳遞的文件,保存至臨時目錄
5 /// <summary> 6 /// 獲取post的文件方法,將圖片文件保存至臨時文件夾,並生成縮略圖 7 /// </summary> 8 /// <param name="req"></param> 9 public static void UploadImgToTempAndCreataThumbnailImage(HttpRequest req) 10 { 11 try 12 { 13 int filesCount = req.Files.Count; //獲取請求流里的文件個數 14 if (filesCount > 0) 15 { 16 bool falg = true; 17 for (int i = 1; i <= filesCount; i++) 18 { 19 string fileName = req.Files[i - 1].FileName; //文件名稱 20 //在此只做普通擴展名過濾,請在程序后台代碼中詳細過濾 21 if (fileName.IndexOf(".exe") > -1) 22 falg = false; 23 if (falg) 24 { 25 //獲取圖片需暫存的臨時目錄 26 string url = UploadFileClass.getTmpRootUrlMapPath() + fileName; 27 lock (url) 28 { 29 //先刪除緩存圖片 30 File.Delete(url); 31 32 //將文件存入臨時目錄 33 req.Files[i - 1].SaveAs(url); 34 35 //效驗文件以及產生縮略圖 36 string newT = fileName; 37 if (File.Exists(url)) 38 { 39 //效驗文件 40 Result rsCheck = checkFile(url); 41 if (rsCheck.Code == 1) 42 { 43 //以 原有文件名后加入后綴: _T 命名縮略圖 44 string FileExtensionName = fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf(".")); 45 string newFileName = fileName.Replace(FileExtensionName, "_T" + FileExtensionName); 46 newT = newFileName; 47 48 //生成文件縮略圖 49 UploadFileClass.CreateThumbnailImage(url, UploadFileClass.getTmpRootUrlMapPath() + newFileName); 50 } 51 } 52 } 53 } 54 } 55 } 56 } 57 catch (Exception ex) 58 { 59 throw ex; 60 } 61 }
傳統服務器端控件文件上傳代碼模塊
4 /// <summary> 5 /// 驗證圖片的格式並上傳並生成圖片縮略圖以及水印圖 6 /// </summary> 7 /// <param name="fup">FileUpload</param> 8 /// <returns></returns> 9 public static Result UploadFile(FileUpload fup) 10 { 11 if (!fup.HasFile) 12 { 13 return new Result(-1,"圖片內容為空!"); 14 } 15 16 try 17 { 18 //上傳文件大小限制 19 int filesizekb = fup.PostedFile.ContentLength / 1024; 20 if (filesizekb > UploadSize) 21 { 22 return new Result(-1, string.Format("文件大小超出限制!文件大小請控制在{0}KB", UploadSize)); 23 } 24 25 //文件擴展名及文件類型驗證 26 if (CheckFileExtension(fup).Code != 1) 27 { 28 return new Result(-1, "請選擇正確的圖片格式!"); 29 } 30 31 //臨時物理路徑 32 string dirPath = getTmpRootUrlMapPath(); 33 if (!Directory.Exists(dirPath)) 34 { 35 Directory.CreateDirectory(dirPath); 36 } 37 string filepath = string.Format("{0}{1}", dirPath, fup.FileName); 38 39 //將文件上傳至臨時目錄 40 fup.PostedFile.SaveAs(filepath); 41 //當上傳成功后,判斷文件類型 42 if (!File.Exists(filepath)) 43 { 44 return new Result(-1, "上傳失敗文件失敗,未找到上傳文件。"); 45 } 46 //安全效驗文件 47 if (checkFile(filepath).Code != 1) 48 return new Result(-1, "非法圖片文件!"); 49 50 //以 原有文件名后加入后綴: _T 命名縮略圖 51 string FileExtensionName = Path.GetExtension(fup.FileName).ToLower(); 52 string newFileName = fup.FileName.Replace(FileExtensionName, "_T" + FileExtensionName); 53 //生成文件縮略圖 54 UploadFileClass.CreateThumbnailImage(filepath, UploadFileClass.getTmpRootUrlMapPath() + newFileName); 55 56 return new Result(1, "文件上傳成功!"); 57 } 58 catch (Exception ex) 59 { 60 throw ex; 61 } 62 }
保存文件模塊
5 /// <summary> 6 /// 保存,實際操作就是將臨時目錄里的圖片移動到站點目錄 7 /// </summary> 8 /// <param name="fileName"></param> 9 /// <returns></returns> 10 public static Result MoveFile(string fileName) 11 { 12 try 13 { 14 string ImgsourceUrl = getTmpRootUrlMapPath() + fileName; 15 if (File.Exists(ImgsourceUrl)) 16 { 17 string ImgThumbnailSourceUrl = getTmpRootUrlMapPath() + fileName.Replace("_T", ""); 18 19 string mNewImgUrl = getImgRootUrlMapPath() + fileName; 20 string mNewImgThumbnailUrl = getImgRootUrlMapPath() + fileName.Replace("_T", ""); 21 22 File.Move(ImgsourceUrl, mNewImgUrl); 23 File.Move(ImgThumbnailSourceUrl, mNewImgThumbnailUrl); 24 } 25 return new Result(1, "保存文件成功"); 26 } 27 catch (Exception ex) 28 { 29 throw ex; 30 } 31 }
js 主要代碼:
1 /// <summary> 2 /// 上傳控件選擇文件夾路徑 3 /// </summary> 4 function selectFile(obj) { 5 //判斷當前上傳控件是否包含文件 6 //obj.files 此屬性支持IE10、firefox、google chromed等瀏覽器 7 if (obj.files != undefined) { 8 if (obj.files.length != 0) { 9 //自動post到接收頁面 10 document.forms[0].action = contralRoot + 'UploadFile.aspx'; 11 document.forms[0].method = "POST"; 12 document.forms[0].enctype = "multipart/form-data"; //允許傳遞文件 13 document.forms[0].target = "frame1"; 14 document.forms[0].submit(); 15 document.getElementById("frame1").height = "500px"; 16 document.getElementById("frame1").width = "100%"; 17 obj.value = ""; 18 } 19 } 20 //ie8及以下版本將調用提交按鈕事件,但會刷新頁面 21 else { 22 document.getElementById("ajaxUF_btnsave").click(); 23 } 24 }
共享盤源碼下載地址:http://pan.baidu.com/s/1mg5OQtq(共享時間有限,如需源碼可加我QQ)
源碼中注意事項:
UploadFileClass.cs 全局變量設置
1 /// <summary> 2 /// 上傳圖片臨時文件夾虛擬目錄,一般為根目錄下,必須保留路徑前后的符號 ‘/’ 3 /// </summary> 4 public static readonly string tmpRootURL = "/AjaxUploadFileContral/temp/"; 5 6 /// <summary> 7 /// 圖片站點目錄,一般為根目錄下,必須保留路徑前后的符號 ‘/’ 8 /// </summary> 9 public static readonly string imgRootURL = "/Image/"; 10 11 /// <summary> 12 /// 定義列表單元格列數,將產生一個N列的表格 13 /// </summary> 14 public static readonly int listCellCount = 5; 15 16 /// <summary> 17 /// 縮略圖寬度 18 /// </summary> 19 public static readonly int ThumbnailImgWidth = 100; 20 /// <summary> 21 /// 縮略圖高度 22 /// </summary> 23 public static readonly int ThumbnailImgHeigth = 100; 24 25 /// <summary> 26 /// 限制文件大小300KB 27 /// </summary> 28 public static readonly int UploadSize = 300;
uploadfile.js 全局變量設置
1 var contralRoot = "/AjaxUploadFileContral/"; //定義全局控件所在目錄
各個瀏覽效果圖:
google chrome:
firefox :
IE8: