jQuery + ashx 實現圖片按比例預覽、異步上傳及顯示

關鍵點:

  • jquery.ajax 方法 和 HTML5 中的 FileReader對象
  • ashx 處理程序
  • asp.net  的 ScriptManager.RegisterStartupScript 調用客戶端js腳本

一、ASP.NET 前臺源碼:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="load_pic.aspx.cs" Inherits="Default2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script>
    <script type="text/javascript" src="Scripts/jquery-extend.js"></script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <!-- 把瀏覽圖片解析爲 base64 字符串 ,通過 jQuery.ajax + ashx 異步保存到數據庫中 -->
        <input type='file' οnchange="readURL(this);" />
        <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="C#後臺讀取顯示" />
        <!-- 存儲 base64 字符串 ,方便在後臺處理 -->
        <asp:HiddenField ID="hf_base64" runat="server" />
    </div>
    <div>
        <img id="img_prev" src="#" alt="your image" /></div>
    </form>
</body>
</html>
二、jquery-extent.js 代碼

/* 客戶端按比例預覽、上傳圖片 要求:jquery-1.4.1.min.js */
//================================================================================================

function readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();

        var maxWidth = 200, maxHeight = 200;
        reader.onload = function (e) {

            var base64 = e.target.result;
            loadbase64(base64, maxWidth, maxHeight);

            $("#hf_base64").val(base64);
        };

        reader.readAsDataURL(input.files[0]);
    }
}
// imgobj : img 標籤對象,根據容器自動調整寬、高
function load_obj_base64(imgobj, base64) {

    maxWidth = $(imgobj).width();
    maxHeight = $(imgobj).height();


    $("<img/>") // 在內存中創建一個img標記
        .attr("src", base64)
        .load(function () {
            var w, h;
            w = this.width;
            h = this.height;


            if (w < maxWidth && h < maxHeight) { }
            else
            { w / h > maxWidth / maxHeight ? this.width = maxWidth : this.height = maxHeight; }


            $(imgobj).replaceWith(this);
        });
}
function loadbase64(base64, maxWidth, maxHeight) {

    $("<img/>") // 在內存中創建一個img標記
        .attr("src", base64).attr("id", "img_prev")
        .load(function () {
            var w, h;
            w = this.width;
            h = this.height;

            // 當圖片比預覽區域小時不做任何改變
            if (w < maxWidth && h < maxHeight) { }
            else
            // 當實際圖片比例大於預覽區域寬高比例時
            // 縮放圖片寬度,反之縮放圖片寬度
            { w / h > maxWidth / maxHeight ? this.width = maxWidth : this.height = maxHeight; }

            $('#img_prev').replaceWith(this);

            $.ajax({
                async: false,
                type: 'POST',
                url: "uploadhandler.ashx",
                data: {
                    file: base64
                },
                success: function (data) {
                    //$j('#img_wait').css('display', 'none');
                },
                beforeSend: function (xhr) {
                    //$j('#img_wait').css('display', 'inline');
                }
            });
        });
}

三、uploadhandler.ashx

<%@ WebHandler Language="C#" Class="uploadhandler" %>

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net;
using System.Web;
using System.Web.Services;


[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class uploadhandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Charset = "utf-8";

        try
        {
            HttpPostedFile file = context.Request.Files["Filedata"];
            DBUtility.IDBHelper dbhelper = new DBUtility.SqlHelper();
            string strSql = "UPDATE [LDZ] set Photo = @imagedata WHERE [ID] = 13;";
            byte[] buffer = null;

            if (file != null)
            {
                buffer = getByte(file);
            }
            else
            {
                string img = context.Request.Params["file"];
                img = img.Substring(img.IndexOf("base64,") + 7);
                buffer = Convert.FromBase64String(img);
            }
            int r = dbhelper.ExecuteNonQuery(WebConfig.DB_CONN, System.Data.CommandType.Text, 
                strSql,new System.Data.SqlClient.SqlParameter("@imagedata", buffer));

            context.Response.Write("1");
        }
        catch (Exception ex)
        {
            context.Response.Write("0");
        }
    }

    private byte[] getByte(HttpPostedFile file)
    {
        byte[] buffer = new byte[file.ContentLength];
        file.InputStream.Read(buffer, 0, buffer.Length);
        return buffer;
    }


    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

    //圖片轉爲base64編碼的字符串
    protected string ImgToBase64String(string Imagefilename)
    {
        try
        {
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(Imagefilename);

            MemoryStream ms = new MemoryStream();
            bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] arr = new byte[ms.Length];
            ms.Position = 0;
            ms.Read(arr, 0, (int)ms.Length);
            ms.Close();
            return Convert.ToBase64String(arr);
        }
        catch (Exception ex)
        {
            return null;
        }
    }

    //base64編碼的字符串轉爲圖片
    protected System.Drawing.Bitmap Base64StringToImage(string strbase64)
    {
        try
        {
            byte[] arr = Convert.FromBase64String(strbase64);
            MemoryStream ms = new MemoryStream(arr);
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms);
            //bmp.Save("test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
            ms.Close();
            return bmp;
        }
        catch (Exception ex)
        {
            return null;
        }
    }
}

四、ASP.NET 後臺代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

public partial class Default2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        DBUtility.IDBHelper dbhelper = new DBUtility.SqlHelper();
        string strSql = "select Photo from [LDZ] WHERE [ID] = 13;";

        DataSet r = dbhelper.ExecuteQuery(WebConfig.DB_CONN, System.Data.CommandType.Text, strSql);

        object imgObj = r.Tables[0].Rows[0]["Photo"];

        string base64 = "data:image/jpeg;base64,";
        if (imgObj != System.DBNull.Value)
        {
            byte[] buffer = (byte[])imgObj;
            base64 += Convert.ToBase64String(buffer);
        }

        string hf_base64 = this.hf_base64.Value;
        ScriptManager.RegisterStartupScript(this, this.GetType(), "",
            "loadbase64('" + base64 + "', 500, 500)", true);
    }
}

注:ajax 方式異步讀取數據庫顯示圖片的方法同上傳一致,使用 ashx 返回base64字符串在客戶端處理即可。

記錄一個讓我糾結良久的問題:

 在Page_Load 函數中,只有第一個用 ScriptManager.RegisterStartupScript 註冊的腳本纔有效

 /// <summary>
    /// 此函數範圍內只有第一個用 ScriptManager.RegisterStartupScript 註冊的腳本纔有效 
    /// </summary>
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            // 首次加載的處理方法
            if (this.Request.Params["lid"] != null)
            {
                // 照片處理,從數據獲取過程省略......
                object imgObj = row["Photo"];
                string base64 = "data:image/jpeg;base64,";
                if (imgObj != System.DBNull.Value)
                {
                    byte[] buffer = (byte[])imgObj;
                    base64 += Convert.ToBase64String(buffer);
                    this.hf_base64.Value = base64;
                    // js腳本 load_obj_base64 是用來在客戶端渲染圖片的
                    string script = "$('#lz_caption strong').text('修改樓長信息');"
	                            +"load_obj_base64($('#photo_lz').parent().next().children('img'),'"+ base64 + "')";
                     ScriptManager.RegisterStartupScript(this, this.GetType(), "",script, true);

	        }

	    }


此示例的前提是瀏覽器必須支持 HTML5 ,但現在的IE對 HTML5支持太爛,如需在 IE中使用,請參考下一篇:IE 中上傳前按比例預覽圖片

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章