jQuery + ashx 实现图片按比例预览、异步上传及显示

关键点:

  • jquery.ajax 方法 和 HTML5 中的 FileReader对象
  • ashx 处理程序
  • asp.net  的 ScriptManager.RegisterStartupScript 调用客户端js脚本

一、ASP.NET 前台源码:

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="load_pic.aspx.cs" Inherits="Default2" %>  
  2.   
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  4. <html xmlns="http://www.w3.org/1999/xhtml">  
  5. <head runat="server">  
  6.     <title></title>  
  7.     <script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script>  
  8.     <script type="text/javascript" src="Scripts/jquery-extend.js"></script>  
  9. </head>  
  10. <body>  
  11.     <form id="form1" runat="server">  
  12.     <div>  
  13.         <!-- 把浏览图片解析为 base64 字符串 ,通过 jQuery.ajax + ashx 异步保存到数据库中 -->  
  14.         <input type='file' onchange="readURL(this);" />  
  15.         <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="C#后台读取显示" />  
  16.         <!-- 存储 base64 字符串 ,方便在后台处理 -->  
  17.         <asp:HiddenField ID="hf_base64" runat="server" />  
  18.     </div>  
  19.     <div>  
  20.         <img id="img_prev" src="#" alt="your image" /></div>  
  21.     </form>  
  22. </body>  
  23. </html>  

二、jquery-extent.js 代码

[javascript] view plaincopy
  1. /* 客户端按比例预览、上传图片 要求:jquery-1.4.1.min.js */  
  2. //================================================================================================  
  3.   
  4. function readURL(input) {  
  5.     if (input.files && input.files[0]) {  
  6.         var reader = new FileReader();  
  7.   
  8.         var maxWidth = 200, maxHeight = 200;  
  9.         reader.onload = function (e) {  
  10.   
  11.             var base64 = e.target.result;  
  12.             loadbase64(base64, maxWidth, maxHeight);  
  13.   
  14.             $("#hf_base64").val(base64);  
  15.         };  
  16.   
  17.         reader.readAsDataURL(input.files[0]);  
  18.     }  
  19. }  
  20. // imgobj : img 标签对象,根据容器自动调整宽、高  
  21. function load_obj_base64(imgobj, base64) {  
  22.   
  23.     maxWidth = $(imgobj).width();  
  24.     maxHeight = $(imgobj).height();  
  25.   
  26.   
  27.     $("<img/>"// 在内存中创建一个img标记  
  28.         .attr("src", base64)  
  29.         .load(function () {  
  30.             var w, h;  
  31.             w = this.width;  
  32.             h = this.height;  
  33.   
  34.   
  35.             if (w < maxWidth && h < maxHeight) { }  
  36.             else  
  37.             { w / h > maxWidth / maxHeight ? this.width = maxWidth : this.height = maxHeight; }  
  38.   
  39.   
  40.             $(imgobj).replaceWith(this);  
  41.         });  
  42. }  
  43. function loadbase64(base64, maxWidth, maxHeight) {  
  44.   
  45.     $("<img/>"// 在内存中创建一个img标记  
  46.         .attr("src", base64).attr("id""img_prev")  
  47.         .load(function () {  
  48.             var w, h;  
  49.             w = this.width;  
  50.             h = this.height;  
  51.   
  52.             // 当图片比预览区域小时不做任何改变  
  53.             if (w < maxWidth && h < maxHeight) { }  
  54.             else  
  55.             // 当实际图片比例大于预览区域宽高比例时  
  56.             // 缩放图片宽度,反之缩放图片宽度  
  57.             { w / h > maxWidth / maxHeight ? this.width = maxWidth : this.height = maxHeight; }  
  58.   
  59.             $('#img_prev').replaceWith(this);  
  60.   
  61.             $.ajax({  
  62.                 async: false,  
  63.                 type: 'POST',  
  64.                 url: "uploadhandler.ashx",  
  65.                 data: {  
  66.                     file: base64  
  67.                 },  
  68.                 success: function (data) {  
  69.                     //$j('#img_wait').css('display', 'none');  
  70.                 },  
  71.                 beforeSend: function (xhr) {  
  72.                     //$j('#img_wait').css('display', 'inline');  
  73.                 }  
  74.             });  
  75.         });  
  76. }  


三、uploadhandler.ashx

  1. <%@ WebHandler Language="C#" Class="uploadhandler" %>  
  2.   
  3. using System;  
  4. using System.Collections.Generic;  
  5. using System.Linq;  
  6. using System.IO;  
  7. using System.Net;  
  8. using System.Web;  
  9. using System.Web.Services;  
  10.   
  11.   
  12. [WebService(Namespace = "http://tempuri.org/")]  
  13. [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  
  14.   
  15. public class uploadhandler : IHttpHandler  
  16. {  
  17.     public void ProcessRequest(HttpContext context)  
  18.     {  
  19.         context.Response.ContentType = "text/plain";  
  20.         context.Response.Charset = "utf-8";  
  21.   
  22.         try  
  23.         {  
  24.             HttpPostedFile file = context.Request.Files["Filedata"];  
  25.             DBUtility.IDBHelper dbhelper = new DBUtility.SqlHelper();  
  26.             string strSql = "UPDATE [LDZ] set Photo = @imagedata WHERE [ID] = 13;";  
  27.             byte[] buffer = null;  
  28.   
  29.             if (file != null)  
  30.             {  
  31.                 buffer = getByte(file);  
  32.             }  
  33.             else  
  34.             {  
  35.                 string img = context.Request.Params["file"];  
  36.                 img = img.Substring(img.IndexOf("base64,") + 7);  
  37.                 buffer = Convert.FromBase64String(img);  
  38.             }  
  39.             int r = dbhelper.ExecuteNonQuery(WebConfig.DB_CONN, System.Data.CommandType.Text,   
  40.                 strSql,new System.Data.SqlClient.SqlParameter("@imagedata", buffer));  
  41.   
  42.             context.Response.Write("1");  
  43.         }  
  44.         catch (Exception ex)  
  45.         {  
  46.             context.Response.Write("0");  
  47.         }  
  48.     }  
  49.   
  50.     private byte[] getByte(HttpPostedFile file)  
  51.     {  
  52.         byte[] buffer = new byte[file.ContentLength];  
  53.         file.InputStream.Read(buffer, 0, buffer.Length);  
  54.         return buffer;  
  55.     }  
  56.   
  57.   
  58.     public bool IsReusable  
  59.     {  
  60.         get  
  61.         {  
  62.             return false;  
  63.         }  
  64.     }  
  65.   
  66.     //图片转为base64编码的字符串  
  67.     protected string ImgToBase64String(string Imagefilename)  
  68.     {  
  69.         try  
  70.         {  
  71.             System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(Imagefilename);  
  72.   
  73.             MemoryStream ms = new MemoryStream();  
  74.             bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);  
  75.             byte[] arr = new byte[ms.Length];  
  76.             ms.Position = 0;  
  77.             ms.Read(arr, 0, (int)ms.Length);  
  78.             ms.Close();  
  79.             return Convert.ToBase64String(arr);  
  80.         }  
  81.         catch (Exception ex)  
  82.         {  
  83.             return null;  
  84.         }  
  85.     }  
  86.   
  87.     //base64编码的字符串转为图片  
  88.     protected System.Drawing.Bitmap Base64StringToImage(string strbase64)  
  89.     {  
  90.         try  
  91.         {  
  92.             byte[] arr = Convert.FromBase64String(strbase64);  
  93.             MemoryStream ms = new MemoryStream(arr);  
  94.             System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms);  
  95.             //bmp.Save("test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);  
  96.             ms.Close();  
  97.             return bmp;  
  98.         }  
  99.         catch (Exception ex)  
  100.         {  
  101.             return null;  
  102.         }  
  103.     }  
  104. }  


四、ASP.NET 后台代码

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.UI;  
  6. using System.Web.UI.WebControls;  
  7. using System.Data;  
  8.   
  9. public partial class Default2 : System.Web.UI.Page  
  10. {  
  11.     protected void Page_Load(object sender, EventArgs e)  
  12.     {  
  13.   
  14.     }  
  15.     protected void Button1_Click(object sender, EventArgs e)  
  16.     {  
  17.         DBUtility.IDBHelper dbhelper = new DBUtility.SqlHelper();  
  18.         string strSql = "select Photo from [LDZ] WHERE [ID] = 13;";  
  19.   
  20.         DataSet r = dbhelper.ExecuteQuery(WebConfig.DB_CONN, System.Data.CommandType.Text, strSql);  
  21.   
  22.         object imgObj = r.Tables[0].Rows[0]["Photo"];  
  23.   
  24.         string base64 = "data:image/jpeg;base64,";  
  25.         if (imgObj != System.DBNull.Value)  
  26.         {  
  27.             byte[] buffer = (byte[])imgObj;  
  28.             base64 += Convert.ToBase64String(buffer);  
  29.         }  
  30.   
  31.         string hf_base64 = this.hf_base64.Value;  
  32.         ScriptManager.RegisterStartupScript(thisthis.GetType(), "",  
  33.             "loadbase64('" + base64 + "', 500, 500)"true);  
  34.     }  
  35. }  

注:ajax 方式异步读取数据库显示图片的方法同上传一致,使用 ashx 返回base64字符串在客户端处理即可。

记录一个让我纠结良久的问题:

 在Page_Load 函数中,只有第一个用 ScriptManager.RegisterStartupScript 注册的脚本才有效

  1. /// <summary>  
  2.    /// 此函数范围内只有第一个用 ScriptManager.RegisterStartupScript 注册的脚本才有效   
  3.    /// </summary>  
  4.    protected void Page_Load(object sender, EventArgs e)  
  5.    {  
  6.        if (!IsPostBack)  
  7.        {  
  8.            // 首次加载的处理方法  
  9.            if (this.Request.Params["lid"] != null)  
  10.            {  
  11.                // 照片处理,从数据获取过程省略......  
  12.                object imgObj = row["Photo"];  
  13.                string base64 = "data:image/jpeg;base64,";  
  14.                if (imgObj != System.DBNull.Value)  
  15.                {  
  16.                    byte[] buffer = (byte[])imgObj;  
  17.                    base64 += Convert.ToBase64String(buffer);  
  18.                    this.hf_base64.Value = base64;  
  19.                    // js脚本 load_obj_base64 是用来在客户端渲染图片的  
  20.                    string script = "$('#lz_caption strong').text('修改楼长信息');"  
  21.                             +"load_obj_base64($('#photo_lz').parent().next().children('img'),'"+ base64 + "')";  
  22.                     ScriptManager.RegisterStartupScript(thisthis.GetType(), "",script, true);  
  23.   
  24.         }  
  25.   
  26.     }  

此示例的前提是浏览器必须支持 HTML5 ,但现在的IE对 HTML5支持太烂,如需在 IE中使用,请参考下一篇:IE 中上传前按比例预览图片

原文地址:https://www.cnblogs.com/jingxinchao/p/3213615.html