Динамическое отображение изображений, полученных из байтового массива на странице - PullRequest
1 голос
/ 30 апреля 2009

Я звоню в веб-сервис, который возвращает неизвестное количество изображений в виде набора байтовых массивов. (Я не могу это изменить)

Мне нужно отобразить каждое изображение на одной веб-странице aspx.

В настоящее время я использую элемент управления Microsoft.Web.GeneratedImage; http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16449 для отображения изображений.

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

Вот код из моего тестового проекта;

     Private Sub btnGetChart_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGetChart.Click
    Dim reportHub As New HubWrapper

    Dim repCharts() As ReportHub.Chart = reportHub.ReportHubChart(Me.ddlReports.SelectedValue, ViewState("params"))

    For Each chart As ReportHub.Chart In repCharts
      Dim sessionKey As String = "img" & System.Guid.NewGuid().ToString

      Dim imgParam As New Microsoft.Web.ImageParameter()
      imgParam.Name = "sessionVar"
      imgParam.Value = sessionKey

      Session(sessionKey) = chart.ChartData

      Dim img As New Microsoft.Web.GeneratedImage
      img.ImageHandlerUrl = "~/chartImageHandler.ashx"
      img.Parameters.Add(imgParam)

      phChart.Controls.Add(img)
    Next
  End Sub

<%@ WebHandler Language="VB" Class="chartImageHandler" %>

Imports System
Imports System.Collections.Specialized
Imports System.Drawing
Imports System.Web
Imports Microsoft.Web

Public Class chartImageHandler
  Inherits ImageHandler

  Implements IRequiresSessionState

  Public Sub New()
    MyBase.New()
    'Set caching settings and add image transformations here
    'EnableServerCache = True

  End Sub

  Public Overrides Function GenerateImage(ByVal parameters As NameValueCollection) As ImageInfo
    Dim byteArry As Byte() = CType(HttpContext.Current.Session(parameters("sessionVar")), Byte())

    HttpContext.Current.Session.Remove(parameters("sessionVar"))

    Return New ImageInfo(byteArry)

  End Function
End Class

Какой самый элегантный способ достижения этого?

Любой ввод приветствуется !!!

РЕДАКТИРОВАТЬ: Дополнительная информация;

  • Изображения с веб-сервиса исходя из служб отчетов SQL.
  • Изображения обычно бывают все время меняется (не реально требование кеширования).
  • Изображения будут определяться пользователем.
  • Веб-сервис вызывается только один раз на страницу.
  • Я на самом деле избавляюсь от изображения из состояние сеанса после сгенерированного изображение использует его, так как изображение не будет нужно было посмотреть снова для в то время.

Ответы [ 3 ]

2 голосов
/ 14 мая 2009

Я полагаю, что вы хотите вызывать свой веб-сервис только один раз за запрос страницы. На самом деле было бы хорошо как-то кэшировать байтовый массив, чтобы веб-сервис больше не вызывался в случае, если пользователь на мгновение отходит от страницы и затем возвращается. В этом случае сохранение байтового массива в сеансе неизбежно. Если вы не использовали элемент управления GeneratedImage, вам все равно нужно было бы где-то сохранить массив байтов.

Я понимаю ваше беспокойство по поводу больших сессий. Основываясь на деталях ваших приложений, есть несколько вещей, которые вы можете сделать, чтобы избежать этого. Все ли изображения относятся к одному пользователю или некоторые изображения доступны пользователям? Часто ли меняются изображения? Если все изображения принадлежат одному пользователю и часто меняются, единственное решение - сохранить их в сеансе. Однако если некоторые пользователи обмениваются изображениями или изображения не должны часто меняться, вы можете создать прокси между веб-службой и веб-приложением. Прокси-сервер сохранит изображения либо в памяти, либо в базе данных (или, возможно, в файловой системе) и сделает их доступными в качестве ресурсов через сопоставление URL-адресов. Вам нужно будет определить это отображение на основе внутренних элементов ваших приложений. Это может быть что-то вроде этого:

http://imageproxy/username/photo123123

Вам также необходимо создать URL, чтобы получить количество доступных изображений:

http://imageproxy/username/imagecount

Нет необходимости использовать компонент GeneratedImage. Вы можете легко создать исходный HTML-код страницы, используя стандартные теги img.

1 голос
/ 15 мая 2009

Вы можете встроить данные изображения непосредственно в источник страницы, используя схему data: URI. Вот описание Википедии . Это не работает с версиями IE до 8, хотя это может сделать его неприемлемым для вашей ситуации.

0 голосов
/ 15 мая 2009

В asp.net вы можете писать и отображать изображения напрямую с помощью объекта ответа, и основные браузеры смогут отображать его. Но вы не можете передать массив байтов, вам нужно передать поток памяти.

получите свой System.Web.HttpContext

Dim ms as New Io.MemoryStream(yourarray)
httpcontext.Response.OutputStream.Write(ms.ToArray,0,ms.Length)

вы помещаете это на страницу display.aspx, и если "yourarray" - это массив байтов, представляющих изображение, браузер отобразит его.

Затем вы можете использовать элемент управления изображением на любой странице (даже в формате HTML) и установить источник изображения на «display.aspx», и ваше изображение будет отображаться.

Теперь, поскольку у вас есть несколько изображений, вам может потребоваться создать элемент управления и создать несколько его экземпляров, по одному для каждого изображения, передающего соответствующий байтовый массив.

...