首页 / 知识

从 ASP.NET 中的 BLOB 条目动态呈现 asp:Image

2023-04-12 20:46:00

从 ASP.NET 中的 BLOB 条目动态呈现 asp:Image

Dynamically Rendering asp:Image from BLOB entry in ASP.NET

我想要实现的就是这个。我想让用户能够上传图像文件,将图像存储在 SQL Server 的 BLOB 中,然后将此图像用作站点其他页面中的徽标。

我通过使用

做到了这一点

1
2
3
4
   Response.Clear();
   Response.ContentType ="image/pjpeg";
   Response.BinaryWrite(imageConents);
   Response.End();

但要做到这一点,我在要显示图像的地方使用了一个用户控件。如果可能的话,我想使用 asp:Image 控件,甚至是纯旧的 html 图像控件。这可能吗?


将\\'Generic Handler\\' 添加到您的Web 项目中,将其命名为Image.ashx 之类的名称。像这样实现它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ImageHandler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        using(Image image = GetImage(context.Request.QueryString["ID"]))
        {    
            context.Response.ContentType ="image/jpeg";
            image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
        }
    }

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

现在只需实现 GetImage 方法来加载具有给定 ID 的图像,就可以使用

1
 

显示它。您可能还想考虑在处理程序中实现某种形式的缓存。请记住,如果要将图像格式更改为 PNG,则需要使用中间 MemoryStream(因为 PNG 需要保存可查找的流)。


您可以将图像的内容直接 BASE64 编码到 SRC 属性中,但是,我相信只有 Firefox 才能将其解析回图像。

我通常做的是创建一个非常轻量级的 HTTPHandler 来提供图像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using System.Web;

namespace Example
{  
    public class GetImage : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            if (context.Request.QueryString("id") != null)
            {
                Blob = GetBlobFromDataBase(id);
                context.Response.Clear();
                context.Response.ContentType ="image/pjpeg";
                context.Response.BinaryWrite(Blob);
                context.Response.End();
            }
        }

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

您可以直接在 img 标签中引用它:

1
<img src="GetImage.ashx?id=111"/>

或者,您甚至可以创建一个服务器控件来为您执行此操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Example.WebControl
{

    [ToolboxData("<{0}:DatabaseImage runat=server></{0}:DatabaseImage>")]
    public class DatabaseImage : Control
    {

        public int DatabaseId
        {
            get
            {
                if (ViewState["DatabaseId" + this.ID] == null)
                    return 0;
                else
                    return ViewState["DataBaseId"];
            }
            set
            {
                ViewState["DatabaseId" + this.ID] = value;
            }
        }

        protected override void RenderContents(HtmlTextWriter output)
        {
            output.Write("<img src='getImage.ashx?id=" + this.DatabaseId +"'/>");
            base.RenderContents(output);
        }
    }
}

这可以像

那样使用

1
<cc:DatabaseImage id="db1" DatabaseId="123" runat="server/>

当然,您可以根据需要在代码隐藏中设置 databaseId。


您不希望在不实施客户端缓存的情况下从数据库提供 blob。

您将需要处理以下标头以支持客户端缓存:

  • 标签
  • 过期
  • 上一次更改
  • 如果匹配
  • 如果不匹配
  • If-Modified-Since
  • If-Unmodified-Since
  • 除非修改自

对于执行此操作的 http 处理程序,请查看:
http://code.google.com/p/talifun-web/wiki/StaticFileHandler

它有一个很好的帮手来提供内容。将数据库流传递给它应该很容易。它还进行服务器端缓存,这应该有助于减轻数据库的一些压力。

如果您决定从数据库、pdf 或大文件提供流媒体内容,处理程序还支持 206 个部分请求。

它还支持 gzip 和 deflate 压缩。

这些文件类型将受益于进一步压缩:

  • css、js、htm、html、swf、xml、xslt、txt
  • 文档、xls、ppt

有些文件类型无法从进一步压缩中受益:

  • pdf(在 IE 中会导致某些版本出现问题,并且通常会被很好地压缩)
  • png、jpg、jpeg、gif、ico
  • wav、mp3、m4a、aac(wav 经常被压缩)
  • 3gp、3g2、asf、avi、dv、flv、mov、mp4、mpg、mpeg、wmv
  • zip、rar、7z、arj

在 MVC 中使用 ASP.Net 这非常容易。你用这样的方法编写控制器:

1
2
3
4
5
6
7
8
9
10
11
12
public FileContentResult Image(int id)
{
    //Get data from database. The Image BLOB is return like byte[]
    SomeLogic ItemsDB= new SomeLogic("[ImageId]=" + id.ToString());
    FileContentResult MyImage = null;
    if (ItemsDB.Count > 0)
    {
        MyImage= new FileContentResult(ItemsDB.Image,"image/jpg");
    }

    return MyImage;
}

在您的 ASP.NET Web 视图中或在此示例中,在您的 ASP.NET Web 窗体中,您可以使用指向您的方法的 URL 填充图像控件,如下所示:

1
2
3
            this.imgExample.ImageUrl ="~/Items/Image/" + MyItem.Id.ToString();
            this.imgExample.Height = new Unit(120);
            this.imgExample.Width = new Unit(120);

瞧。不需要 HttpModules 麻烦。


将代码添加到处理程序以返回具有适当 mime 类型的图像字节。然后您可以将 url 添加到您的处理程序中,就像它是一个图像一样。例如:

1
<img src="myhandler.ashx?imageid=5">

有意义吗?


我们实际上刚刚发布了一些有助于解决此类问题的类:

http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16449

具体来说,请查看 DatabaseImage 示例。


动态图像用户上传

最新内容

相关内容

热门文章

推荐文章

标签云

猜你喜欢