Динамическое отображение изображений, полученных из байтового массива, на странице

StackOverflow https://stackoverflow.com/questions/807739

Вопрос

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

Мне нужно отображать каждое изображение на одной веб-странице 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 Reporting Services.
  • Изображения обычно меняются все время (без реального требования к кэшированию).
  • Изображения будут зависеть от пользователя.
  • Веб-сервис вызывается только один раз на странице.
  • Я на самом деле удаляю изображение из состояния сеанса после того, как сгенерированное изображение использует его, так как изображение не нужно будет просмотреть снова на некоторое время.
Это было полезно?

Решение

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

Другие советы

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

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

http://imageproxy/username/photo123123

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

http://imageproxy/username/imagecount

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

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

Получите ваш System.Web.HttpContext

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top