簡體   English   中英

如何在Web瀏覽器中從數據庫中將ASP.NET中的圖像作為文件加載?

[英]How to load an image in ASP.NET from a database as a file in a web browser?

我在SQL Server數據庫中有一些圖像。 我想在用戶單擊按鈕時顯示它們,但是我希望它們作為文件加載到瀏覽器中,以便當用戶調整窗口大小時,圖像會自動調整大小。

例如,在Firefox中,如果轉到“文件”->“打開文件...”並選擇計算機上的圖像,則它將拖動到新窗口中,並在拖動滾動條時為您調整大小。 我的問題是,如何將圖像作為文件從SQL Server數據庫加載到瀏覽器中? 我在用戶單擊GridView內的視圖的窗體上有以下代碼:

<script type="text/javascript">
    function ShowImageInNewPage(url_add) {
        window.open(url_add, 'ViewScreenshot', 'resizable=yes,scrollbars = yes');
    }
</script>

<asp:GridView 
 ID="grdTrades" 
 runat="server" 

 <... removed some properties for brevity ...>
 >
 <Columns>
  <asp:CommandField ShowSelectButton="true" ButtonType="Link" SelectText="Select" /> 

  <.. removed some columns for brevity ...>

  <asp:TemplateField HeaderText="Screenshot" >
   <ItemTemplate>
    <input type="button" size="x-small" value="View" onclick="javascript:ShowImageInNewPage('DisplayImage.aspx?screenshotId=<%# Eval("screenshotId") %>');" />
   </ItemTemplate>
  </asp:TemplateField>
 </Columns>
</asp:GridView>

DisplayImage.aspx具有以下代碼:

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {        
        if (Request.QueryString["screenshotId"] != null)
        {            
            int screenshotId= int.Parse(Request.QueryString["screenshotId"]);
            imgScreenshot.ImageUrl = "App_Handlers/ImageHandler.ashx?screenshotId=" + screenshotId;            
        }
    }    
</script>

<html>
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Image ID="imgScreenshot" runat="server" />
    </div>
    </form>
</body>
</html>

App_Handlers / ImageHandler.ashx具有以下代碼:

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

using System;
using System.Web;
using System.Data;
using DatabaseComponent;

public class ImageHandler : IHttpHandler {

    public void ProcessRequest (HttpContext context) {

        if (context.Request.QueryString["screenshotId"] != null)
        {
            int screenshotId = int.Parse(context.Request.QueryString["screenshotId"]);

            DBUtil DB = new DBUtil();
            DataTable dt = DB.GetScreenshot(screenshotId);

            if (dt != null)
            {
                Byte[] bytes = (Byte[])dt.Rows[0]["screenshot"];
                context.Response.Buffer = true;
                context.Response.Charset = "";
                context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
                context.Response.ContentType = dt.Rows[0]["contentType"].ToString();
                context.Response.AddHeader("content-disposition", "attachment;filename=" + dt.Rows[0]["fileName"].ToString());
                context.Response.BinaryWrite(bytes);               
                context.Response.Flush();
                context.Response.End();
            }
        }        
    }

    public bool IsReusable {
        get {
            return false;
        }
    }
}

這是DisplayImage.aspx的響應頭

Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 10 Nov 2010 13:13:37 GMT
X-AspNet-Version: 4.0.30319
Transfer-Encoding: chunked
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: image/JPG
Connection: Close

我已經將原來的問題更改為現在使用圖像處理程序,謝謝@leppie。 感謝您的光臨!

UPDATE

現在,我已將DisplayImage.aspx更改為此代碼,但是現在我得到了一些真正的怪異行為。 當我單擊圖像鏈接時,將加載此頁面,firefox詢問是否要保存DisplayImage.aspx。 到底是怎么回事? 如何使Firefox將圖像作為文件加載?

DisplayImage.aspx:

<%@ Page Language="C#" ContentType="image/*"  %>

<script runat="server">        
</script>

<html>
<head runat="server">
    <title></title>
</head>
<body>
    <img  src="App_Handlers/ImageHandler.ashx?screenshotId=<%=Request.QueryString["screenshotId"]%>" /> 
</body>
</html>

如果我從Page聲明中刪除ContentType,則圖像會加載到新窗口中,但是圖像不會縮放,也不會自動調整大小。 拔頭發...

您不應該使用頁面來返回圖像數據。 相反,您應該使用HttpHandler。 HttpHandler是實現IHttpHandler接口的類。 IHttpHandler接口比Page更為底層。 Page實際上確實實現了IHttpHandler本身,但是Page的目的是返回html,這就是為什么您不應該使用它來返回圖像數據。

如果要使用頁面(例如ImageLoad.aspx)執行此操作,則在Page_Load中執行以下操作即可:

protected void Page_Load(object sender, EventArgs e)
{
    HttpResponse response = HttpContext.Current.Response;

    response.Clear();
    response.ContentType = "image/png";

    Image outputImage = (Load your image here)
    MemoryStream ms = new MemoryStream();
    outputImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    ms.WriteTo(response.OutputStream);
    outputImage.Dispose();
    ms.Close();

    response.End();
}

或者使用處理程序:

public class ImageHandler : IHttpHandler
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        try
        {
            HttpResponse response = context.Response;

            response.Clear();
            response.ContentType = "image/png";

            Image outputImage = (Load your image here)
            MemoryStream ms = new MemoryStream();
            outputImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            ms.WriteTo(response.OutputStream);
            outputImage.Dispose();
            ms.Close();

            response.End();
        }
        catch
        {
            context.Response.End();
        }
    }
}

只需根據指定圖像的方式(大概是請求參數),用相關代碼替換(在此處加載圖像)即可。

如其他答案中所建議,如果要保存一些時鍾周期,請在請求上設置相關的緩存頭。

一旦從數據庫中獲取了byte []

將Response.MimeType設置為適當的值,例如jpeg圖像的“ image / jpg”,然后執行Response.Write或Response.WriteBinary將byte []寫入響應。

如果要瀏覽器緩存文件,則可以選擇設置“緩存頭”。

我已經設法解決了。 我可以完全刪除DisplayImage.aspx,而直接從調用頁面直接調用圖像處理程序,因此GridView現在看起來像這樣:

<script type="text/javascript">
    function ShowImageInNewPage(url_add) {
        window.open(url_add, 'ViewScreenshot', 'resizable=yes,scrollbars = yes');
    }
</script>

<asp:GridView 
 ID="grdTrades" 
 runat="server" 

 <... removed some properties for brevity ...>
 >
 <Columns>
  <asp:CommandField ShowSelectButton="true" ButtonType="Link" SelectText="Select" /> 

  <.. removed some columns for brevity ...>

  <asp:TemplateField HeaderText="Screenshot" >
   <ItemTemplate>
    <input runat="server" visible='<%# Eval("screenshotId") != DBNull.Value %>' type="button" value='View...' onclick='<%# "ShowImageInNewPage(\"App_Handlers/ImageHandler.ashx?screenshotId=" + Eval("screenshotId") + "\")" %>' />
   </ItemTemplate>
  </asp:TemplateField>
 </Columns>
</asp:GridView>

當用戶單擊按鈕時,圖像將加載到新窗口中,並且可以通過拖動窗口角在客戶端上調整大小。 感謝大家對此的幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM