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?

 13
Author: Dominik, 2008-08-22

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).

 18
Author: Fredrik Kalseth,
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.

 9
Author: FlySwat,
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
 5
Author: Taliesin,
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.
 2
Author: Fidel Orozco,
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.

 0
Author: Brad Wilson,
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?

 0
Author: Ryan Farley,
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