使用SWFUpload實(shí)現(xiàn)無刷新上傳圖片
在做項(xiàng)目時(shí),需要用到一個(gè)圖片的無刷新上傳,之前聽說過SWFUpload,于是想要通過SWFUpload來進(jìn)行圖片的無刷新上傳,由于我的項(xiàng)目屬于是ASP.NET項(xiàng)目,所以本文著重講解ASP.NET 的使用,個(gè)人感覺示例基本給的很清晰,參考文檔進(jìn)行開發(fā),并非難事
0. 首先下載swfUpload 包,在下載的包中有samples文件夾,samples下有demos文件夾,打開demos文件夾可看到如下圖所示結(jié)構(gòu)
我們待會(huì)會(huì)用到的包括,swfupload目錄下的文件,css不建議使用以避免與自己寫的CSS相沖突使得頁面布局完全亂掉,如果要添加樣式最好自己寫
打開 applicationdemo.net目錄會(huì)看到這樣的結(jié)構(gòu)
打開index.html可以看到這樣的頁面
點(diǎn)擊NET2.0下的Application Demo C#項(xiàng)
添加資源引用
將要引用的資源包含到項(xiàng)目中(包括swfupload文件夾下的文件與,demo下的資源文件,handlers.js是在demo中js目錄下的js文件)
首先熟悉demo,將demo中的頁面包含到項(xiàng)目中
在Defaut.aspx頁面中使用swfUpload組件進(jìn)行圖片的無刷新上傳直接運(yùn)行,看效果,大概了解基本過程
修改handlers.js文件
我的項(xiàng)目文件結(jié)構(gòu)大概是這樣的
我的處理文件上傳的頁面是ImageUploadHandler.ashx,獲取縮略圖的頁面是GetThumbHandler.ashx,Thumbnail.cs是demo中App_Code文件夾中的文件,個(gè)人覺得像這種只處理邏輯功能而不展現(xiàn)頁面的最好都用一般處理程序來實(shí)現(xiàn)。由于哪個(gè)文件處理上傳哪個(gè)文件生成縮略圖已經(jīng)在handlers.js文件中寫死了,所以必須要修改handlers.js文件以能夠使頁面正常運(yùn)行
最終修改版匯總
Thumbnail
/// <summary> /// 縮略圖 /// </summary> public class Thumbnail { public Thumbnail(string id, byte[] data) { this.ID = id; this.Data = data; } private string id; /// <summary> /// 圖片id /// </summary> public string ID { get { return this.id; } set { this.id = value; } } private byte[] thumbnail_data; /// <summary> /// 圖片的二進(jìn)制數(shù)據(jù) /// </summary> public byte[] Data { get { return this.thumbnail_data; } set { this.thumbnail_data = value; } } private string contentType; /// <summary> /// 圖片對(duì)應(yīng)的MIME類型 /// </summary> public string ContentType { get { return contentType; } set { contentType = value; } } }
Html Demo
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Upload Images</title> <script src="swfupload/swfupload.js"></script> <script src="swfupload/handlers.js"></script> <script> //注:div的id名稱最好不要改,要改的話在handlers.js文件中也要進(jìn)行修改,div的名稱已經(jīng)在handlers.js文件中寫死 var swfu; window.onload = function () { swfu = new SWFUpload({ // 后臺(tái)設(shè)置,設(shè)置處理上傳的頁面 upload_url: "/Handlers/ImageUploadHandler.ashx", // 文件上傳大小限制設(shè)置 file_size_limit: "3 MB", //文件類型設(shè)置,多種格式以英文中的分號(hào)分開 file_types: "*.jpg;*.png", //文件描述,與彈出的選擇文件對(duì)話框相關(guān) file_types_description : "Images file", //設(shè)置上傳文件數(shù)量限制 file_upload_limit: "1", //事件處理程序,最好不要改,事件處理程序已在handlers.js文件中定義 // Event Handler Settings - these functions as defined in Handlers.js // The handlers are not part of SWFUpload but are part of my website and control how // my website reacts to the SWFUpload events. file_queue_error_handler : fileQueueError, file_dialog_complete_handler : fileDialogComplete, upload_progress_handler : uploadProgress, upload_error_handler : uploadError, upload_success_handler : uploadSuccess, upload_complete_handler : uploadComplete, // 上傳按鈕設(shè)置 button_image_url : "/swfupload/images/XPButtonNoText_160x22.png", button_placeholder_id: "spanButtonPlaceholder", button_width: 160, button_height: 22, button_text : '請(qǐng)選擇圖片 (最大3M)', button_text_style : '.button { font-family: Helvetica, Arial, sans-serif; font-size: 14pt; } .buttonSmall { font-size: 10pt; }', button_text_top_padding: 1, button_text_left_padding: 5, // swfupload.swf flash設(shè)置 flash_url : "/swfupload/swfupload.swf", //自定義的其他設(shè)置 custom_settings : { upload_target: "divFileProgressContainer" }, // 是否開啟調(diào)試模式,調(diào)試時(shí)可以設(shè)置為true,發(fā)布時(shí)設(shè)置為false debug: false }); } </script> </head> <body> <form id="form1"> <div id="content"> <h2>Upload Images Demo</h2> <div id="swfu_container" style="margin: 0px 10px;"> <div> <span id="spanButtonPlaceholder"></span> </div> <div id="divFileProgressContainer" style="height: 75px;"></div> <div id="thumbnails"></div> </div> </div> </form> </body> </html>
ImageUploadHandler
/// <summary> /// 圖片上傳處理 /// </summary> public class ImageUploadHandler : IHttpHandler, IRequiresSessionState { /// <summary> /// 記錄日志 logger /// </summary> private static Common.LogHelper logger = new Common.LogHelper(typeof(ImageUploadHandler)); public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; System.Drawing.Image thumbnail_image = null; System.Drawing.Image original_image = null; System.Drawing.Bitmap final_image = null; System.Drawing.Graphics graphic = null; MemoryStream ms = null; try { //驗(yàn)證用戶是否登錄,是否有權(quán)限上傳 if (context.Session["User"]==null) { context.Response.Write("沒有上傳圖片的權(quán)限!"); context.Response.End(); return; } //獲取上傳文件 HttpPostedFile image_upload = context.Request.Files["Filedata"]; //獲取文件擴(kuò)展名 string fileExt = System.IO.Path.GetExtension(image_upload.FileName).ToLower(); //驗(yàn)證文件擴(kuò)展名是否符合要求,是否是允許的圖片格式 if (fileExt!=".jpg"&&fileExt!=".png") { return; } //當(dāng)前時(shí)間字符串 string timeString = DateTime.Now.ToString("yyyyMMddHHmmssfff"); //圖片保存虛擬路徑構(gòu)建 string path = "/Upload/"+timeString + fileExt; //保存到Session 變量中 context.Session["imgPath"] = path; //獲取、構(gòu)建要上傳文件的物理路徑 string serverPath = context.Server.MapPath("~/"+path); //保存圖片到服務(wù)器 image_upload.SaveAs(serverPath); //記錄日志 logger.Debug("圖片上傳成功!"); #region 生成縮略圖 // 獲取上傳圖片的文件流 original_image = System.Drawing.Image.FromStream(image_upload.InputStream); // 根據(jù)原圖計(jì)算縮略圖的寬度和高度,及縮放比例等~~ int width = original_image.Width; int height = original_image.Height; int target_width = 100; int target_height = 100; int new_width, new_height; float target_ratio = (float)target_width / (float)target_height; float image_ratio = (float)width / (float)height; if (target_ratio > image_ratio) { new_height = target_height; new_width = (int)Math.Floor(image_ratio * (float)target_height); } else { new_height = (int)Math.Floor((float)target_width / image_ratio); new_width = target_width; } new_width = new_width > target_width ? target_width : new_width; new_height = new_height > target_height ? target_height : new_height; //創(chuàng)建縮略圖 final_image = new System.Drawing.Bitmap(target_width, target_height); graphic = System.Drawing.Graphics.FromImage(final_image); graphic.FillRectangle(new System.Drawing.SolidBrush(System.Drawing.Color.Black), new System.Drawing.Rectangle(0, 0, target_width, target_height)); int paste_x = (target_width - new_width) / 2; int paste_y = (target_height - new_height) / 2; graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; /* new way */ //graphic.DrawImage(thumbnail_image, paste_x, paste_y, new_width, new_height); graphic.DrawImage(original_image, paste_x, paste_y, new_width, new_height); // Store the thumbnail in the session (Note: this is bad, it will take a lot of memory, but this is just a demo) ms = new MemoryStream(); //將縮略圖保存到內(nèi)存流中 final_image.Save(ms, System.Drawing.Imaging.ImageFormat.Png); #endregion //建立 Thumbnail對(duì)象 Thumbnail thumb = new Thumbnail(timeString, ms.GetBuffer()); //保存縮略圖到Session 中,也可以保存成文件,保存為圖片 context.Session["file_info"] = thumb; //操作成功,返回HTTP狀態(tài)碼設(shè)置為 200 context.Response.StatusCode = 200; //輸出縮略圖的id,在生成縮略圖時(shí)要用到 context.Response.Write(thumb.ID); } catch(Exception ex) { // 出現(xiàn)異常,返回 500,服務(wù)器內(nèi)部錯(cuò)誤 context.Response.StatusCode = 500; //記錄錯(cuò)誤日志 logger.Error(ex); } finally { // 釋放資源 if (final_image != null) final_image.Dispose(); if (graphic != null) graphic.Dispose(); if (original_image != null) original_image.Dispose(); if (thumbnail_image != null) thumbnail_image.Dispose(); if (ms != null) ms.Close(); context.Response.End(); } } public bool IsReusable { get { return false; } } }
GetThumbHandler
/// <summary> /// 獲取縮略圖 /// </summary> public class GetThumbHandler : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //獲取縮略圖id string id = context.Request.QueryString["id"]; //id為空則返回錯(cuò)誤 if (String.IsNullOrEmpty(id)) { context.Response.StatusCode = 404; context.Response.Write("Not Found"); context.Response.End(); return; } //從Session中獲取縮略圖文件 Thumbnail thumb= context.Session["file_info"] as Thumbnail; //判斷id是否一致 if (thumb.ID == id) { //重新設(shè)置響應(yīng)MIME 類型 context.Response.ContentType = "image/png"; //輸出二進(jìn)制流信息 context.Response.BinaryWrite(thumb.Data); //截止輸出 context.Response.End(); return; } //沒有找到相應(yīng)圖片,返回404 context.Response.StatusCode = 404; context.Response.Write("Not Found"); context.Response.End(); } public bool IsReusable { get { return false; } } }
handlers.js 文件
function fileQueueError(file, errorCode, message) { try { var imageName = "error.gif"; var errorName = ""; if (errorCode == SWFUpload.errorCode_QUEUE_LIMIT_EXCEEDED) { errorName = "上傳文件過多!"; } if (errorName != "") { alert(errorName); return; } switch (errorCode) { case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: imageName = "zerobyte.gif"; break; case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: imageName = "toobig.gif"; break; case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: default: alert(message); break; } //添加圖片,注意路徑 addImage("/swfupload/images/" + imageName); } catch (ex) { this.debug(ex); } } function fileDialogComplete(numFilesSelected, numFilesQueued) { try { if (numFilesQueued > 0) { this.startUpload(); } } catch (ex) { this.debug(ex); } } function uploadProgress(file, bytesLoaded) { try { var percent = Math.ceil((bytesLoaded / file.size) * 100); var progress = new FileProgress(file, this.customSettings.upload_target); progress.setProgress(percent); if (percent === 100) { progress.setStatus("正在創(chuàng)建縮略圖..."); progress.toggleCancel(false, this); } else { progress.setStatus("正在上傳..."); progress.toggleCancel(true, this); } } catch (ex) { this.debug(ex); } } function uploadSuccess(file, serverData) { try { //添加縮略圖~~~ //修改這里來設(shè)置生成縮略圖的頁面 addImage("/Handlers/GetThumbHandler.ashx?id=" + serverData); var progress = new FileProgress(file, this.customSettings.upload_target); progress.setStatus("縮略圖創(chuàng)建成功!"); progress.toggleCancel(false); } catch (ex) { this.debug(ex); } } function uploadComplete(file) { try { /* I want the next upload to continue automatically so I'll call startUpload here */ if (this.getStats().files_queued > 0) { this.startUpload(); } else { var progress = new FileProgress(file, this.customSettings.upload_target); progress.setComplete(); progress.setStatus("圖片上傳成功"); progress.toggleCancel(false); } } catch (ex) { this.debug(ex); } } function uploadError(file, errorCode, message) { var imageName = "error.gif"; var progress; try { switch (errorCode) { case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED: try { progress = new FileProgress(file, this.customSettings.upload_target); progress.setCancelled(); progress.setStatus("上傳操作被取消"); progress.toggleCancel(false); } catch (ex1) { this.debug(ex1); } break; case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED: try { progress = new FileProgress(file, this.customSettings.upload_target); progress.setCancelled(); progress.setStatus("上傳停止!"); progress.toggleCancel(true); } catch (ex2) { this.debug(ex2); } case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED: imageName = "uploadlimit.gif"; break; default: alert(message); break; } addImage("/swfupload/images/" + imageName); } catch (ex3) { this.debug(ex3); } } function addImage(src) { var newImg = document.createElement("img"); newImg.style.margin = "5px"; document.getElementById("thumbnails").appendChild(newImg); if (newImg.filters) { try { newImg.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 0; } catch (e) { // If it is not set initially, the browser will throw an error. This will set it if it is not set yet. newImg.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + 0 + ')'; } } else { newImg.style.opacity = 0; } newImg.onload = function () { fadeIn(newImg, 0); }; newImg.src = src; } function fadeIn(element, opacity) { var reduceOpacityBy = 5; var rate = 30; // 15 fps if (opacity < 100) { opacity += reduceOpacityBy; if (opacity > 100) { opacity = 100; } if (element.filters) { try { element.filters.item("DXImageTransform.Microsoft.Alpha").opacity = opacity; } catch (e) { // If it is not set initially, the browser will throw an error. This will set it if it is not set yet. element.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + opacity + ')'; } } else { element.style.opacity = opacity / 100; } } if (opacity < 100) { setTimeout(function () { fadeIn(element, opacity); }, rate); } } /* ****************************************** * FileProgress Object * Control object for displaying file info * ****************************************** */ function FileProgress(file, targetID) { this.fileProgressID = "divFileProgress"; this.fileProgressWrapper = document.getElementById(this.fileProgressID); if (!this.fileProgressWrapper) { this.fileProgressWrapper = document.createElement("div"); this.fileProgressWrapper.className = "progressWrapper"; this.fileProgressWrapper.id = this.fileProgressID; this.fileProgressElement = document.createElement("div"); this.fileProgressElement.className = "progressContainer"; var progressCancel = document.createElement("a"); progressCancel.className = "progressCancel"; progressCancel.href = "#"; progressCancel.style.visibility = "hidden"; progressCancel.appendChild(document.createTextNode(" ")); var progressText = document.createElement("div"); progressText.className = "progressName"; progressText.appendChild(document.createTextNode(file.name)); var progressBar = document.createElement("div"); progressBar.className = "progressBarInProgress"; var progressStatus = document.createElement("div"); progressStatus.className = "progressBarStatus"; progressStatus.innerHTML = " "; this.fileProgressElement.appendChild(progressCancel); this.fileProgressElement.appendChild(progressText); this.fileProgressElement.appendChild(progressStatus); this.fileProgressElement.appendChild(progressBar); this.fileProgressWrapper.appendChild(this.fileProgressElement); document.getElementById(targetID).appendChild(this.fileProgressWrapper); fadeIn(this.fileProgressWrapper, 0); } else { this.fileProgressElement = this.fileProgressWrapper.firstChild; this.fileProgressElement.childNodes[1].firstChild.nodeValue = file.name; } this.height = this.fileProgressWrapper.offsetHeight; } FileProgress.prototype.setProgress = function (percentage) { this.fileProgressElement.className = "progressContainer green"; this.fileProgressElement.childNodes[3].className = "progressBarInProgress"; this.fileProgressElement.childNodes[3].style.width = percentage + "%"; }; FileProgress.prototype.setComplete = function () { this.fileProgressElement.className = "progressContainer blue"; this.fileProgressElement.childNodes[3].className = "progressBarComplete"; this.fileProgressElement.childNodes[3].style.width = ""; }; FileProgress.prototype.setError = function () { this.fileProgressElement.className = "progressContainer red"; this.fileProgressElement.childNodes[3].className = "progressBarError"; this.fileProgressElement.childNodes[3].style.width = ""; }; FileProgress.prototype.setCancelled = function () { this.fileProgressElement.className = "progressContainer"; this.fileProgressElement.childNodes[3].className = "progressBarError"; this.fileProgressElement.childNodes[3].style.width = ""; }; FileProgress.prototype.setStatus = function (status) { this.fileProgressElement.childNodes[2].innerHTML = status; }; FileProgress.prototype.toggleCancel = function (show, swfuploadInstance) { this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden"; if (swfuploadInstance) { var fileID = this.fileProgressID; this.fileProgressElement.childNodes[0].onclick = function () { swfuploadInstance.cancelUpload(fileID); return false; }; } };
以上所述就是本文的全部內(nèi)容了,希望對(duì)大家學(xué)習(xí)asp.net能夠有所幫助。
相關(guān)文章
Server Application Unavailable出現(xiàn)的原因及解決方案小結(jié)
今天在服務(wù)器安裝了個(gè).net 4.0 framework(原本有1.0和2.0的),配置好站點(diǎn)后,選擇版本為4.0,訪問出錯(cuò),asp.net經(jīng)常會(huì)出現(xiàn)這個(gè)問題,這里腳本之家簡單的給整理下2012-05-05實(shí)例講解.NET中資源文件的創(chuàng)建與使用
資源文件顧名思義就是存放資源的文件。資源文件在程序設(shè)計(jì)中有著自身獨(dú)特的優(yōu)勢,他獨(dú)立于源程序,這樣資源文件就可以被多個(gè)程序使用2011-12-12編寫的vs2005水晶報(bào)表程序在vs2008下正常使用的一些實(shí)現(xiàn)方法
以前用vs2005編寫的WEB程序,現(xiàn)在使用vs2008時(shí)總是出現(xiàn)水晶報(bào)表的錯(cuò)誤,不能使用。經(jīng)過本人實(shí)踐,總結(jié)一下錯(cuò)誤原因。2009-09-09ASP.NET MVC5網(wǎng)站開發(fā)添加文章(八)
小編整理的ASP.NET MVC5網(wǎng)站開發(fā)是一系列的文章體系,大家要一篇篇的仔細(xì)閱讀,今天這篇文章主要介紹了ASP.NET MVC5網(wǎng)站開發(fā)添加文章,需要的朋友可以參考下2015-09-09Asp.net使用SignalR實(shí)現(xiàn)發(fā)送圖片
這篇文章主要為大家詳細(xì)介紹了Asp.net使用SignalR實(shí)現(xiàn)發(fā)送圖片,需要的朋友可以參考下2016-04-04asp.net 驗(yàn)證字符串是否為純數(shù)字檢測函數(shù)
如何驗(yàn)證字符串是否為純數(shù)字2010-03-03