Visualizzazione di immagini derivate da una matrice di byte in modo dinamico su una pagina
Domanda
Sto chiamando un servizio web che sta restituendo una quantità sconosciuta di immagini sotto forma di una raccolta di array di byte. (Non posso cambiarlo)
Devo visualizzare ogni immagine su una singola pagina web aspx.
Attualmente sto usando il controllo Microsoft.Web.GeneratedImage; http://www.codeplex.com/aspnet/Release/ProjectReleases. aspx? ReleaseId = 16449 per visualizzare le immagini.
Il problema che ho è che dal momento che il controllo chiama un file di codice separato per caricare il contenuto dell'immagine, sto usando lo stato della sessione per memorizzare il bytearray, di cui non sono eccessivamente felice.
Ecco un po 'di codice dal mio progetto di test;
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
Qual è il modo più elegante per raggiungere questo obiettivo?
Qualsiasi input benvenuto !!!
EDIT: informazioni aggiuntive;
- Le immagini dal servizio web sono proveniente da SQL Reporting Services.
- Le immagini sarebbero generalmente cambiando tutto il tempo (non reale requisito di memorizzazione nella cache).
- Le immagini sarebbero specifiche dell'utente.
- Il servizio web viene chiamato solo una volta per pagina.
- Sto effettivamente eliminando l'immagine da stato della sessione dopo il generato l'immagine lo utilizza, come non sarà l'immagine doveva essere visualizzato di nuovo per a po '.
Soluzione
Puoi incorporare i dati dell'immagine direttamente nell'origine della pagina usando lo schema URI data:
. Ecco la descrizione di Wikipedia . Tuttavia, ciò non funziona con le versioni di IE precedenti alla 8, il che potrebbe renderlo inaccettabile per la tua situazione.
Altri suggerimenti
Suppongo che tu voglia chiamare il tuo servizio web solo una volta per richiesta di pagina. In effetti, sarebbe utile in qualche modo memorizzare nella cache l'array di byte, in modo che il servizio Web non venga richiamato nel caso in cui l'utente si allontani momentaneamente dalla pagina e poi ritorni. In tal caso, è inevitabile salvare l'array di byte nella sessione. Se non hai usato il controllo GeneratedImage, avresti comunque bisogno di salvare l'array di byte da qualche parte.
Comprendo le tue preoccupazioni riguardo alle grandi sessioni. Sulla base dei dettagli delle tue applicazioni, ci sono alcune cose che potresti fare per evitarlo. Tutte le immagini si riferiscono a un singolo utente o alcune immagini sono condivise tra gli utenti? Le immagini cambiano spesso? Se tutte le immagini appartengono a un singolo utente e cambiano frequentemente, salvarle nella sessione è l'unica soluzione. Se tuttavia alcuni utenti condividono immagini o non si prevede che le immagini cambino frequentemente, è possibile creare un proxy tra il servizio Web e l'applicazione Web. Il proxy salverà le immagini, in memoria o in un database (o forse nel file system) e le renderà disponibili come risorse, tramite una mappatura URL. Dovresti definire questa mappatura, sulla base degli interni delle tue applicazioni. Potrebbe essere qualcosa del genere:
http://imageproxy/username/photo123123
Devi anche creare un URL per restituire il numero di immagini disponibili:
http://imageproxy/username/imagecount
Non sarebbe necessario utilizzare il componente GeneratedImage. Puoi facilmente creare l'origine html della pagina usando i tag img standard.
In asp.net puoi scrivere e immagini direttamente con l'oggetto response e i principali browser saranno in grado di visualizzarlo. Ma non è possibile passare un array di byte, è necessario passare un flusso di memoria.
ottieni il tuo System.Web.HttpContext
Dim ms as New Io.MemoryStream(yourarray)
httpcontext.Response.OutputStream.Write(ms.ToArray,0,ms.Length)
lo metti in una pagina display.aspx e se " yourarray " è una matrice di byte che rappresenta un'immagine che verrà visualizzata dal browser.
Puoi quindi utilizzare un controllo immagine su qualsiasi pagina (anche semplice HTML) e impostare la sorgente dell'immagine su " display.aspx " e la tua immagine verrà visualizzata.
Ora, poiché hai più immagini, potresti dover creare un controllo e crearne più istanze, una per ogni immagine che passa l'array di byte corrispondente.