Динамическая визуализация asp: изображение из BLOB-записи в ASP.NET - PullRequest
13 голосов
/ 22 августа 2008

Чего я хочу достичь, так это. Я хочу дать пользователю возможность загружать файл изображения, сохранять изображение в BLOB в SQL Server, а затем использовать это изображение в качестве логотипа на других страницах сайта.

Я сделал это с помощью

   Response.Clear();
   Response.ContentType = "image/pjpeg";
   Response.BinaryWrite(imageConents);
   Response.End();

но для этого я использую пользовательский элемент управления в том месте, где хочу показать изображение. Я хочу сделать это, если это возможно, используя элемент управления asp: Image или даже чистый старый HTML-элемент управления изображением. Это возможно?

Ответы [ 6 ]

18 голосов
/ 22 августа 2008

Добавьте «универсальный обработчик» в ваш веб-проект, назовите его как-то так: 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 для загрузки изображения с заданным идентификатором, и вы можете использовать

<asp:Image runat="server" ImageUrl="~/Image.ashx?ID=myImageId" /> 

, чтобы отобразить его. Возможно, вы захотите подумать и о реализации некоторой формы кэширования в обработчике. И помните, что если вы хотите изменить формат изображения на PNG, вам нужно использовать промежуточный MemoryStream (поскольку PNG требуют, чтобы был сохранен ищущий поток).

9 голосов
/ 22 августа 2008

Вы можете 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 в коде.

5 голосов
/ 22 февраля 2010

Вы не хотите обслуживать большие двоичные объекты из базы данных без реализации кэширования на стороне клиента.

Вам потребуется обработать следующие заголовки для поддержки кэширования на стороне клиента:

  • ETag
  • 1008 * Истекает *
  • Last-Modified
  • If-Match
  • If-None-Match
  • If-Modified-Since
  • If-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
  • документ, 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
2 голосов
/ 08 октября 2013

Используя 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 вы можете заполнить элемент управления изображением с URL-адресом вашего метода следующим образом:

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

Вуаля. Не надо было хлопот HttpModules.

0 голосов
/ 22 августа 2008

Добавьте код в обработчик, чтобы вернуть байты изображения с соответствующим типом MIME. Затем вы можете просто добавить URL в ваш обработчик, как будто это изображение. Например:

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

Имеет смысл?

0 голосов
/ 22 августа 2008

Мы только что выпустили несколько классов, которые помогают именно с такими вещами:

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

В частности, ознакомьтесь с образцом DatabaseImage.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...