jQuery+ashx画像のスケールプレビュー、非同期アップロード、表示を実現


キー:
  • jquery.ajaxメソッドとHTML 5の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' onchange="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を使用してbase 64文字列を返してクライアントで処理すればよい.
    長い間悩んでいた問題を記録します.
    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);
    
    	        }
    
    	    }
    
    

    この例では、ブラウザがHTML 5をサポートする必要があることを前提としていますが、現在のIEはHTML 5をサポートしていません.IEで使用する場合は、次の編を参照してください.IEにアップロードする前に画像を比例プレビューしてください.