2013-04-15 13 views
5

Sono qui che il mio ingegno termina.Ridimensionamento delle immagini utilizzando il gestore HTTP ASP.Net, alcune immagini non vengono visualizzate

Ho un gestore HTTP (ImageHandler.ashx) che invia le immagini verso il basso (ridimensionate), è un gestore HTTP standard (provato con Reusable true e false) che utilizza Image.GetThumbnailImage per ridimensionare e restituire la miniatura.

Ho un controllo Datalist asp che ha una tabella con un controllo immagine html.

 <asp:DataList ID="listImg" runat="server" RepeatColumns="4" RepeatDirection="Horizontal" 
     ShowFooter="false" ShowHeader="false"> 
     <ItemTemplate> 
      <table width="220px"> 
       <tr width="100%"> 
        <td> 
         <img src="Scripts/ImageHandler.ashx?width=125&image=Upload/<%# DataBinder.Eval(Container.DataItem, "photo") %>"        
        </td> 
       </tr> 
      </table> 
     </ItemTemplate> 
    </asp:DataList> 

Come è possibile osservare i parametri di cui il Gestore ha bisogno sono la larghezza e il Percorso immagine.

Questo Datalist è associato a un datatable (ImageData) che fornisce l'elenco di immagini da visualizzare.

Beh, tutto ha un senso fino ad ora, ora ecco il problema - Dire che sto caricando 5 immagini, cioè il mio DataTable ImageData ha 5 righe, è un dato che verranno visualizzate solo 3-4 immagini, le restanti appena arrivato con una X rossa, come quando non hai alcuna immagine. Ora, se si guarda il codice e navigare alla src immagine come -

http://localhost:3540/Scripts/ImageHandler.ashx?width=150&image=Upload/Test123.jpg 

vedrete l'immagine, sono tutti lì non ci sono immagini mancanti. Ricarica e sono tornati.

Ho eseguito questo in Firefox e aperto Firebug e quando ho guardato attraverso la scheda Immagini, TUTTE le immagini sono state restituite secondo Firebug (Stato 200 OK e vedo l'immagine nella scheda Risposta), è come il server Web appena non mostra alcuni di loro. Nota che NON sono sempre le immagini che impiegano più tempo a elaborare/caricare quelle mancanti, alcune di quelle casuali.

Cosa potrebbe succedere qui?

Grazie.

MODIFICA 1 - Aggiunta del codice gestore (originale), abbiamo ereditato questo codice. Ho rimosso Caching dal codice qui, ma le miniature FYI una volta generate vengono memorizzate nella cache.

public class ImageHandler : IHttpHandler{ 
public int _width; 
public int _height; 
public int _percent; 
public string imageURL; 


public void ProcessRequest(HttpContext context) 
{ 
    try 
    { 
     Bitmap bitOutput; 

     string appPath = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ImagePath"]); 

     String strArquivo = appPath + context.Request.QueryString["image"].Replace("/", "\\"); 

     if (!(String.IsNullOrEmpty(context.Request["width"]))) 
     { 
      Bitmap bitInput = GetImage(context); 

      if (SetHeightWidth(context, bitInput)) 
      { bitOutput = ResizeImage(bitInput, _width, _height, _percent); } 
      else { bitOutput = bitInput; } 

      context.Response.ContentType = "image/jpeg"; 
      bitOutput.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); 
     } 

     return; 

    } 
    catch (Exception ex) { /*HttpContext.Current.Response.Write(ex.Message);*/ } 
} 


/// <summary> 
/// Get the image requested via the query string. 
/// </summary> 
public Bitmap GetImage(HttpContext context) 
{ 
    try 
    { 
     if (context.Cache[("ImagePath-" + context.Request.QueryString["image"])] == null) 
     { 
      string appPath = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ImagePath"]); 

      appPath = appPath + context.Request.QueryString["image"].Replace("/", "\\"); 
      Bitmap bitOutput; 
      imageURL = appPath; 


      bitOutput = new Bitmap(appPath); 
      return bitOutput; 
     } 
     else 
     { 
      return (Bitmap)context.Cache[("ImagePath-" + context.Request.QueryString["image"])]; 
     } 

    } 
    catch (Exception ex) { throw ex; } 
}  


/// <summary> 
/// Set the height and width of the handler class. 
/// </summary> 
public bool SetHeightWidth(HttpContext context, Bitmap bitInput) 
{ 
    try 
    { 
     double inputRatio = Convert.ToDouble(bitInput.Width)/Convert.ToDouble(bitInput.Height); 

     if (!(String.IsNullOrEmpty(context.Request["width"])) && !(String.IsNullOrEmpty(context.Request["height"]))) 
     { 
      _width = Int32.Parse(context.Request["width"]); 
      _height = Int32.Parse(context.Request["height"]); 
      return true; 
     } 
     else if (!(String.IsNullOrEmpty(context.Request["width"]))) 
     { 
      _width = Int32.Parse(context.Request["width"]); 
      _height = Convert.ToInt32((_width/inputRatio)); 
      if (_width == 400 &&_height > 500) 
      { 
       _height = 500; 
       _width = Convert.ToInt32(500 * inputRatio); 
      } 
      else if (_width == 125 && _height > 200) 
      { 
       _height = 200; 
       _width = Convert.ToInt32(200 * inputRatio); 
      } 
      return true; 
     } 
     else if (!(String.IsNullOrEmpty(context.Request["height"]))) 
     { 
      _height = Int32.Parse(context.Request["height"]); 
      _width = Convert.ToInt32((_height * inputRatio)); 
      return true; 
     } 
     else if (!(String.IsNullOrEmpty(context.Request["percent"]))) 
     { 
      _height = bitInput.Height; 
      _width = bitInput.Width; 
      _percent = Int32.Parse(context.Request["percent"]); 
      return true; 
     } 
     else 
     { 
      _height = bitInput.Height; 
      _width = bitInput.Width; 
      return false; 
     } 

    } 
    catch (Exception ex) { throw ex; } 
} 

/// <summary> 
/// Resizes bitmap using high quality algorithms. 
/// </summary> 
public static Bitmap ResizeImage(Bitmap originalBitmap, int newWidth, int newHeight, int newPercent) 
{ 
    try 
    { 
     if (newPercent != 0) 
     { 
      newWidth = Convert.ToInt32(originalBitmap.Width * (newPercent * .01)); 
      newHeight = Convert.ToInt32(originalBitmap.Height * (newPercent * .01)); 
     } 

     Bitmap inputBitmap = originalBitmap; 
     Bitmap resizedBitmap = new Bitmap(newWidth, newHeight, PixelFormat.Format64bppPArgb); 

     Graphics g = Graphics.FromImage(resizedBitmap); 
     g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
     g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; 
     g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
     Rectangle rectangle = new Rectangle(0, 0, newWidth, newHeight); 
     g.DrawImage(inputBitmap, rectangle, 0, 0, inputBitmap.Width, inputBitmap.Height, GraphicsUnit.Pixel); 
     g.Dispose(); 

     return resizedBitmap; 

    } 
    catch (Exception ex) { throw ex; } 
} 


public bool IsReusable 
{ 
    get 
    { 
     return true; 
    } 
}} 

EDIT 2 Se qualcuno vuole mettere alla prova tutta questa cosa, qui è il codice che raccoglie le immagini a caso da una cartella predefinita per creare il DataTable (ImageData) che l'aspDataList (listImg) è legato a -

 System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(Server.MapPath("Upload")); 
     System.IO.FileInfo[] files = dirInfo.GetFiles(); 

     int fileCount = files.Length; 

     System.Data.DataTable ImageData = new System.Data.DataTable(); 
     System.Data.DataColumn dCol = new System.Data.DataColumn("photo"); 
     ImageData.Columns.Add(dCol); 


     System.Random rnd = new Random(); 
     int nxtNumber = 0; 

     System.Data.DataRow dRow = null; 

     string fileName = string.Empty; 

     for (int i = 0; i < 20; i++) 
     { 
      dRow = ImageData.NewRow(); 
      nxtNumber = rnd.Next(fileCount); 
      while (!files[nxtNumber].Extension.Equals(".jpg")) 
      { 
       nxtNumber = rnd.Next(fileCount); 
      } 
      fileName = files[nxtNumber].Name; 

      dRow["photo"] = fileName; 

      ImageData.Rows.Add(dRow); 
     } 
     listImg.DataSource = ImageData; 
     listImg.DataBind(); 
+0

Puoi pubblicare il codice gestore? Forse c'è qualcosa lì dentro che a volte restituisce un'immagine vuota. Inoltre, quando dici che le immagini hanno ottenuto 200 stati in Firebug, hanno anche dei contenuti? Dovrebbe dirti il ​​numero di byte restituiti. –

+0

Sì, mostra il contenuto (immagine) e la dimensione. Inoltre, non è sempre la stessa immagine che appare vuota, se dovessi visualizzare lo stesso insieme più volte senza la memorizzazione nella cache, è un'immagine casuale che scompare. Inserirò un po 'il codice del gestore, una volta rimossi i file non necessari da lì. – Rakesh

+0

questa non è una risposta, ma un suggerimento. potresti voler controllare questo pacchetto nuget: http://nuget.org/packages/ImageResizer ha diversi pacchetti extra per ridimensionare gif, ecc. –

risposta

0

Bene, ecco la cosa divertente: lo stesso codice sul server si comporta in modo più prevedibile, potrei avere ancora un paio di immagini mancanti, ma ora è come 1 mancante tra 30-40 in media contro 1 da ogni 5 nel mio ambiente locale. Poiché queste richieste erano asincrone poteva avere qualcosa a che fare con la CPU effettiva della macchina su cui era in esecuzione, il server era appena più adatto a gestire più richieste rispetto al mio misero laptop?

In entrambi i modi ho modificato il codice, quindi a questo punto non sono coinvolti ridimensionamenti, il codice del gestore recupera solo immagini ridimensionate e tutto va bene a questo punto.

Grazie a tutti per i vostri input.

0

cercare di codificare querystring di URL, ad esempio:

http://localhost:3540/Scripts/ImageHandler.ashx?width=150&image=Upload/Test123.jpg 

urlencode a

http://localhost:3540/Scripts/ImageHandler.ashx?width%3D150%26image%3DUpload%2FTest123.jpg 
0

Suppongo che il tuo codice effettivo includa il /> alla fine del tag img ??? In caso contrario, provare ad aggiungere prima questo e riprovare.

Non proprio una risposta, ma si potrebbe provare a cambiare il tag img per un asp: Label e visualizzare il nome del file come testo piuttosto che visualizzare l'immagine solo per vedere se la DataTable è in costruzione in modo corretto. Dato che sei in grado di vedere le immagini quando accedi direttamente al gestore di immagini, direi che ha qualcosa a che fare con la costruzione datatable nel codebehind.

Ogni volta che ho fatto qualcosa di simile, di solito immagazzino le immagini nel DB SQL e uso il gestore di immagini per restituire l'immagine con l'ID del record nella stringa di query. Ciò significa che stai restituendo una tabella di record esistente piuttosto che doverla creare in base al contenuto di una cartella.

Problemi correlati