Dynamiczne renderowanie asp:obraz z wpisu BLOB w ASP.NET
Chcę to osiągnąć. Chcę dać użytkownikowi możliwość przesłania pliku obrazu, przechowywania obrazu w BLOB w SQL Server, a następnie używać tego obrazu jako logo na innych stronach witryny.
Zrobiłem to używając
Response.Clear();
Response.ContentType = "image/pjpeg";
Response.BinaryWrite(imageConents);
Response.End();
Ale aby to zrobić, używam kontrolki użytkownika w miejscu, w którym chcę pokazać obraz. Chcę to zrobić, jeśli to możliwe, używając kontrolki asp:Image, lub nawet czystej starej kontroli obrazu html. Czy to możliwe?
6 answers
Dodaj 'Generic Handler' do swojego projektu internetowego, nazwij go czymś takim jak Image.ashx. Zaimplementuj to tak:
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;
}
}
}
Teraz wystarczy zaimplementować metodę GetImage, aby załadować obraz o podanym ID i można użyć
<asp:Image runat="server" ImageUrl="~/Image.ashx?ID=myImageId" />
Aby go wyświetlić. Możesz też pomyśleć o zaimplementowaniu jakiejś formy buforowania w programie obsługi. I pamiętaj, jeśli chcesz zmienić format obrazu na PNG, musisz użyć pośredniego strumienia MemoryStream (ponieważ PNGs wymaga strumienia seekable, aby być zapisane).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-22 06:25:31
Możesz BASE64 kodować zawartość obrazu bezpośrednio do atrybutu SRC, jednak wierzę, że tylko Firefox przetworzy to z powrotem do obrazu.
To, co zwykle robię, to tworzenie bardzo lekkiego Httphandlera do obsługi obrazów:
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;
}
}
}
}
Możesz odnieść się do tego bezpośrednio w tagu img:
<img src="GetImage.ashx?id=111"/>
Lub możesz nawet utworzyć kontrolkę serwera, która zrobi to za Ciebie:
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);
}
}
}
To może być używane jak
<cc:DatabaseImage id="db1" DatabaseId="123" runat="server/>
I oczywiście można ustawić databaseId w kodzie w razie potrzeby.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-22 06:30:10
Nie chcesz obsługiwać obiektów blob z bazy danych bez implementacji buforowania po stronie klienta.
Będziesz musiał obsługiwać następujące nagłówki, aby obsługiwać buforowanie po stronie klienta:
- ETag
- wygasa
- Ostatnio Zmodyfikowane
- If-Match
- If-None-Match
- If-Modified-Since
- If-Unmodified-Since
- Unless-Modified-Since
Dla obsługi http, która to robi, sprawdź out: http://code.google.com/p/talifun-web/wiki/StaticFileHandler
Ma ładny pomocnik do serwowania treści. Powinien być łatwy do przekazania w strumieniu bazy danych do niego. Robi również buforowanie po stronie serwera, co powinno pomóc złagodzić presję na bazę danych.
Jeśli kiedykolwiek zdecydujesz się na przesyłanie strumieniowe treści z bazy danych, plików PDF lub dużych plików, obsługa obsługuje również 206 częściowych żądań.
Obsługuje również gzip i deflate kompresja.
Te typy plików będą korzystać z dalszej kompresji:
- css, JS, htm, html, swf, xml, xslt, txt
- doc, xls, ppt
Istnieją pewne typy plików, które nie skorzystają z dalszej kompresji:
- pdf (powoduje problemy z niektórymi wersjami w IE i zwykle jest dobrze skompresowany)
- png, jpg, jpeg, gif, ico
- wav, mp3, M4A, aac (wav jest często kompresowany)
- 3gp, 3G2, asf, avi, dv, flv, mov, mp4, MPG, mpeg, wmv
- zip, rar, 7z, arj
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-22 10:47:46
Za pomocą ASP.Net z MVC jest to dość łatwe do przodu. Kodujesz kontroler z taką metodą:
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;
}
W Twoim ASP.NET Web View lub w tym przykładzie, w Twoim ASP.NET formularz internetowy możesz wypełnić kontrolkę obrazka z adresem URL do swojej metody w następujący sposób:
this.imgExample.ImageUrl = "~/Items/Image/" + MyItem.Id.ToString();
this.imgExample.Height = new Unit(120);
this.imgExample.Width = new Unit(120);
Voilá. Nie potrzeba było kłopotów z HttpModules.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-09 13:58:55
Właśnie wypuściliśmy kilka klas, które pomagają w tego typu sprawach:
Http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16449
W szczególności, sprawdź próbkę bazy danych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-22 06:22:01
Dodaj kod do funkcji obsługi, aby zwrócić bajty obrazu z odpowiednim typem mime. Następnie możesz po prostu dodać adres url do obsługi, jakby był to obraz. Na przykład:
<img src="myhandler.ashx?imageid=5">
Ma sens?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-22 06:26:21