Динамическое рендеринг asp: изображение из записи BLOB в ASP.NET
Я хочу добиться этого. Я хочу дать пользователю возможность загрузить файл изображения, сохранить изображение в BLOB в SQL Server, а затем использовать это изображение в качестве логотипа на других страницах сайта.
Я сделал это, используя
Response.Clear();
Response.ContentType = "image/pjpeg";
Response.BinaryWrite(imageConents);
Response.End();
но для этого я использую элемент управления User в том месте, где я хочу показать изображение. Я хочу сделать это, если возможно, используя asp: Image control или даже чистый старый элемент управления html. Возможно ли это?
Спасибо всем
Ответы
Ответ 1
Добавьте "общий обработчик" в свой веб-проект, назовите его что-то вроде Image.ashx. Реализуйте это следующим образом:
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, и вы можете использовать
<asp:Image runat="server" ImageUrl="~/Image.ashx?ID=myImageId" />
чтобы отобразить его. Возможно, вам захочется подумать и о реализации некоторой формы кэширования в обработчике. И помните, если вы хотите изменить формат изображения на PNG, вам нужно использовать промежуточный MemoryStream (потому что для PNG требуется, чтобы поисковый поток был сохранен).
Ответ 2
Вы можете BASE64 кодировать содержимое изображения непосредственно в атрибут SRC, однако я считаю, что только Firefox будет анализировать это обратно в изображение.
Что я обычно делаю, так это создать очень легкий HTTPHandler для обслуживания изображений:
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:
<img src="GetImage.ashx?id=111"/>
Или вы даже можете создать серверный элемент управления, который сделает это за вас:
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);
}
}
}
Это можно использовать как
<cc:DatabaseImage id="db1" DatabaseId="123" runat="server/>
И, конечно же, вы можете установить databaseId в коде, если необходимо.
Ответ 3
Вы не хотите показывать капли из базы данных без кэширования на стороне клиента.
Вам потребуется обработать следующие заголовки для поддержки кеширования на стороне клиента:
- ETag
- Истекает
- Last-Modified
- Если-Match
- If-None-Match
- If-Modified-Since
- Если-Unmodified-С
- Unless-Modified-Since
Для обработчика http, который делает это, проверьте:
http://code.google.com/p/talifun-web/wiki/StaticFileHandler
У него есть хороший помощник для обслуживания контента. Это должно быть легко передать в поток базы данных к нему. Он также выполняет кеширование на стороне сервера, которое должно помочь смягчить некоторое давление на базу данных.
Если вы когда-либо решили обслуживать потоковый контент из базы данных, PDF файлов или больших файлов, обработчик также поддерживает 206 частичных запросов.
Он также поддерживает сжатие gzip и deflate.
Эти типы файлов выиграют от дальнейшего сжатия:
- css, js, htm, html, swf, xml, xslt, txt
- doc, 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
Ответ 4
Использование ASP.Net с MVC довольно просто. Вы управляете контроллером таким способом:
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 или в этом примере в вашей веб-форме ASP.NET вы можете заполнить Image Control с помощью URL-адреса для вашего метода следующим образом:
this.imgExample.ImageUrl = "~/Items/Image/" + MyItem.Id.ToString();
this.imgExample.Height = new Unit(120);
this.imgExample.Width = new Unit(120);
Вуаля. Не требуется HttpModules.
Ответ 5
На самом деле мы только что выпустили несколько классов, которые помогают именно в этом:
http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16449
В частности, проверьте образец DatabaseImage.
Ответ 6
Добавьте код в обработчик, чтобы вернуть байты изображения с соответствующим типом mime. Затем вы можете просто добавить URL-адрес к своему обработчику, как образ. Например:
<img src="myhandler.ashx?imageid=5">
Имеют смысл?