none
Afficher une Image à partir d'un Byte[] RRS feed

  • Question

  • Bonjour,

    J'aimerai a partir d'un byte[] que j'ai en base pouvoir l'afficher dans ma page aspx!

    voici comment je récupère mon image :

    MemoryStream ms = new MemoryStream(buff); 
    Image img = Image.FromStream(ms);
    return img;


    ou buff est mon tableau de byte!


    maintenant

    J'aimerai pouvoir afficher mon image Big Smile

    mon img est de type System.Drawing.Image, et j'aimerai afficher dans un WebControl.Image

    mais je n'est pas trouvé de solution :x

    avez-vous des idées, ou autres astuces pour afficher mes images?
    (sachant que se sera des images affichées dans une gridView et que je passe
    dans la RowDataBound pour la conversion)

    merki


    mercredi 9 janvier 2008 15:40

Réponses

  • Bonjour,

    Vous ne pouvez pas en Web insérer les données d'une image dans la page. Un control Image contient l'url de l'image à afficher non les données comme en WinForm.

    Pour que vous puissiez afficher en web une image dont les données sont dans la page le plus simple est :

    1. Créer une page aspx sans aucun contenu a part la balise
    2. Ajoutez ce code coté code beside :

    Extrait de code

    byte[] data = this.GetImageData(this.Request.QueryString["id"]);

    this.Response.BinaryWrite(data);

     

     

    La méthode GetImageData doit retourner les données de l'image en base en se basant sur l'id spécifié.

    Si votre page s'appel Image.aspx par exemple il ne reste plus qu'a affecter à la propriété ImageUrl de votre controle image la valeur "Image.aspx?id=..."

     

    Le top serait pour vous de créer votre propre HttpHandler faisant ce travail et ensuite de l'associer à une extension custom (.imgx par exemple), l'url de vos image deviendraient : <id de l'image>.imgx

     

    Guillaume

    mercredi 9 janvier 2008 16:45
  • Comme j'avais un peu de temps, voila le code utilisant un IHttpHandler :

     

    Extrait de code

    public class ImageHandler : IHttpHandler

    {

    #region Constructors

     

    public ImageHandler()

    {

    }

     

    #endregion

     

    #region IHttpHandler Members

     

    public bool IsReusable

    {

    get { return true; }

    }

     

    public void ProcessRequest(HttpContext context)

    {

    string fileName = Path.GetFileNameWithoutExtension(context.Request.Path) + ".png";

    byte[] data = this.GetData(fileName);

     

    context.Response.Clear();

    context.Response.Buffer = true;

     

    // mettre le ContentType et le filename en fonction des données

    context.Response.ContentType = "image/png";

    context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", fileName));

     

    context.Response.ContentEncoding = System.Text.Encoding.Default;

    context.Response.Charset = string.Empty;

     

    context.Response.BinaryWrite(data);

    context.Response.Flush();

    }

     

    private byte[] GetData(string fileName)

    {

    using (FileStream fs = File.Open(HttpContext.Current.Server.MapPath(fileName), FileMode.Open, FileAccess.Read, FileShare.Read))

    {

    byte[] data = new byte[fs.Length];

    fs.Read(data, 0, data.Length);

     

    return data;

    }

    }

     

    #endregion

    }

     

     

    Dans le fichier web.config il faut ajouter sous  :

     

    Extrait de code

    <httpHandlers>

    <add verb="*" path="*.imgx" type="ImageHandler"/>

    </httpHandlers>

     

     

    Si vous utilisez IIS, il faut aussi déclarer l'extension .imgx dans Application Configuration/Mappings et la faire utiliser le même données que pour .aspx

     

    Sinon pour l'adapter à vos besoin, il faut modifier la méthode GetData qui pour l'instant lit un fichier sur le HD et la création du fileName (je rajoute automatiquement .png dans mon exemple).

     

    L'interet de cette méthode est que si vous appeler l'url de l'image directement votre navigateur vous proposera de sauver l'image ou l'ouvrira. En plus vous ne passer pas par l'ensemble des évènements d'une page classique (Init, Load, PreRender, Render)

     

    Guillaume

    mercredi 9 janvier 2008 17:17
  • Bonjour,

    Si vous voulez, vous pouvez utiliser les paramètres de la QueryString, dans ce cas il faudra utiliser context.Request.QueryString pour récupérer les données.

    Je viens de tester avec IIS et je n'ai pas de problème. Voila ce que j'ai :

    • Dans le projet web, j'ai dans le répertoire App_Code le fichier ImageHandler.cs
    • Dans le projet web, j'ai ajouté au fichier web.config les lignes

      <httpHandlers>

      <add verb="*" path="*.imgx" type="ImageHandler"/>

      </httpHandlers>

      Dans la partie system.web
    • Dans l'interface IIS

      • bouton droit sur le site web puis Propriétés

      • onglet "Home Directory", bouton Configuration

      • onglet "Mappings", bouton Add

        • Executable : "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\aspnet_isapi.dll"

        • Extension : ".imgx"

        • Verbs : Limit to "GET,HEAD,POST,DEBUG"

        • Script engine coché

        • Verify that file exists non coché

    Avec tout cela ça marche.

     

    Guillaume

    vendredi 11 janvier 2008 13:12
  • Bonjour,

    C'est bizzard pour la query string car en testant l'url avec "MonImage32.imgx?id=MonId" j'arrive bien à avoir la valeur en faisant context.Request.QueryString["id"].

     

    Guillaume

    vendredi 11 janvier 2008 13:52
  • Bonjour,

    L'intéret est au niveau de performance. Si vous utilisez votre propre HttpHandler, il traitera la requête dès la réception de la requête. Si vous utilisez une page aspx, vous passerez par le HttpHandler gérant les pages qui rajoute pas mal de traitement : chargement/sauvegarde du ViewState (qui est vide), les différents évènements (PreInit, Init, PreLoad, Load, PreRender, ...)

     

    Pour avoir une vue plus précise, vous trouverez sur la page la liste des actions obligatoires par lesquelles passe une requête :

     

    http://msdn2.microsoft.com/fr-fr/library/ms178473.aspx

     

    Dans le 15, il est indiqué que la méthode ProcessRequest est appelée sur le HttpHandler approprié. Si vous avez votre propre HttpHandler, votre code s'éxecute à ce moment. Si vous avez le HttpHandler gérant les pages aspx, voila la liste des actions effectuée par le ProcessRequest :

     

    http://msdn2.microsoft.com/fr-fr/library/ms178472.aspx

     

    Guillaume

    jeudi 24 janvier 2008 11:12

Toutes les réponses

  • Bonjour,

    Vous ne pouvez pas en Web insérer les données d'une image dans la page. Un control Image contient l'url de l'image à afficher non les données comme en WinForm.

    Pour que vous puissiez afficher en web une image dont les données sont dans la page le plus simple est :

    1. Créer une page aspx sans aucun contenu a part la balise
    2. Ajoutez ce code coté code beside :

    Extrait de code

    byte[] data = this.GetImageData(this.Request.QueryString["id"]);

    this.Response.BinaryWrite(data);

     

     

    La méthode GetImageData doit retourner les données de l'image en base en se basant sur l'id spécifié.

    Si votre page s'appel Image.aspx par exemple il ne reste plus qu'a affecter à la propriété ImageUrl de votre controle image la valeur "Image.aspx?id=..."

     

    Le top serait pour vous de créer votre propre HttpHandler faisant ce travail et ensuite de l'associer à une extension custom (.imgx par exemple), l'url de vos image deviendraient : <id de l'image>.imgx

     

    Guillaume

    mercredi 9 janvier 2008 16:45
  • Comme j'avais un peu de temps, voila le code utilisant un IHttpHandler :

     

    Extrait de code

    public class ImageHandler : IHttpHandler

    {

    #region Constructors

     

    public ImageHandler()

    {

    }

     

    #endregion

     

    #region IHttpHandler Members

     

    public bool IsReusable

    {

    get { return true; }

    }

     

    public void ProcessRequest(HttpContext context)

    {

    string fileName = Path.GetFileNameWithoutExtension(context.Request.Path) + ".png";

    byte[] data = this.GetData(fileName);

     

    context.Response.Clear();

    context.Response.Buffer = true;

     

    // mettre le ContentType et le filename en fonction des données

    context.Response.ContentType = "image/png";

    context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", fileName));

     

    context.Response.ContentEncoding = System.Text.Encoding.Default;

    context.Response.Charset = string.Empty;

     

    context.Response.BinaryWrite(data);

    context.Response.Flush();

    }

     

    private byte[] GetData(string fileName)

    {

    using (FileStream fs = File.Open(HttpContext.Current.Server.MapPath(fileName), FileMode.Open, FileAccess.Read, FileShare.Read))

    {

    byte[] data = new byte[fs.Length];

    fs.Read(data, 0, data.Length);

     

    return data;

    }

    }

     

    #endregion

    }

     

     

    Dans le fichier web.config il faut ajouter sous  :

     

    Extrait de code

    <httpHandlers>

    <add verb="*" path="*.imgx" type="ImageHandler"/>

    </httpHandlers>

     

     

    Si vous utilisez IIS, il faut aussi déclarer l'extension .imgx dans Application Configuration/Mappings et la faire utiliser le même données que pour .aspx

     

    Sinon pour l'adapter à vos besoin, il faut modifier la méthode GetData qui pour l'instant lit un fichier sur le HD et la création du fileName (je rajoute automatiquement .png dans mon exemple).

     

    L'interet de cette méthode est que si vous appeler l'url de l'image directement votre navigateur vous proposera de sauver l'image ou l'ouvrira. En plus vous ne passer pas par l'ensemble des évènements d'une page classique (Init, Load, PreRender, Render)

     

    Guillaume

    mercredi 9 janvier 2008 17:17
  • merci pour vos réponses!

    je n'ai pas eu le temps de m'y mettre avant Wink
    j'ai réussi avec votre premiere solution, je vais tenter la 2e maintenant Smile
    vendredi 11 janvier 2008 10:14
  • Une question :x

    comment je peux récuperer mon id?

    vu que c'est une classe et quelle est utilisé directement par le compilateur via le web.config, je ne peux plus utiliser le "this.Request"!

    merki
    vendredi 11 janvier 2008 10:30
  • Bonjour,

    J'ai du mal à comprendre la question, dans quelle solution voulez vous récupérer votre id ? Dans la solution 1 vous pouvez utiliser this.Request normalement. Dans la solution 2 j'ai modifier le code pour prendre en compte directement le nom de la page appelée (sans l'extension) comme étant l'id via le code :

     

    Extrait de code
    string fileName = Path.GetFileNameWithoutExtension(context.Request.Path)

     

     

    Donc pour utiliser la solution 2, si votre image à comme id "MonImage34" par exemple, il faudra écrire dans votre page html le code suivant :

     

    Extrait de code

    <img src="MonImage34.imgx"/>

     

     

    Guillaume
    vendredi 11 janvier 2008 11:07
  • merci, je n'avais pas compris Wink
    vu que j'avais plusieurs parametres a passer, j'ai utilisé l'astuce de tout mettre dans le nom et de faire ensuite un split dessus!

    j'ai l"impression que ma page ImageHandler n'est pas appelée (je ne rentre pas dedans dans Debug, et mon image n'est pas affifée)

    j'ai ajouté dans les propriétés du site Répertoire(onglet)\configuration(bouton)\mappage(onglet) la nouvelle extension .imgx avec les memes parametres que .aspx!

    c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll

    Limité à GET,HEAD,POST,DEBUG

    vendredi 11 janvier 2008 12:28
  • Bonjour,

    Si vous voulez, vous pouvez utiliser les paramètres de la QueryString, dans ce cas il faudra utiliser context.Request.QueryString pour récupérer les données.

    Je viens de tester avec IIS et je n'ai pas de problème. Voila ce que j'ai :

    • Dans le projet web, j'ai dans le répertoire App_Code le fichier ImageHandler.cs
    • Dans le projet web, j'ai ajouté au fichier web.config les lignes

      <httpHandlers>

      <add verb="*" path="*.imgx" type="ImageHandler"/>

      </httpHandlers>

      Dans la partie system.web
    • Dans l'interface IIS

      • bouton droit sur le site web puis Propriétés

      • onglet "Home Directory", bouton Configuration

      • onglet "Mappings", bouton Add

        • Executable : "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\aspnet_isapi.dll"

        • Extension : ".imgx"

        • Verbs : Limit to "GET,HEAD,POST,DEBUG"

        • Script engine coché

        • Verify that file exists non coché

    Avec tout cela ça marche.

     

    Guillaume

    vendredi 11 janvier 2008 13:12
  • merci ça a marché!

    par contre le context.Request.QueryString est vide:x
    (donc je suis repassé à mon astuce pas propre avec le split pour au moins tester que a marchait)
    vendredi 11 janvier 2008 13:24
  • Bonjour,

    C'est bizzard pour la query string car en testant l'url avec "MonImage32.imgx?id=MonId" j'arrive bien à avoir la valeur en faisant context.Request.QueryString["id"].

     

    Guillaume

    vendredi 11 janvier 2008 13:52
  • Nickel!

    apres un exemple, c'est tout de suite mieux Wink

    merci bcp Guillaume
    vendredi 11 janvier 2008 14:22
  • Bonjour,

    une question tardive mais mieux vaut tard que jamais Big Smile

    quel est l'avantage de l'utilisation du HttpHandler?

    Je viens de refaire des tests avec la 1ere méthode (une page Image.aspx) tous ce que j'ai remarqué c'est qu'au chargement de la page, les images se chargent au fur et à mesure!

    merki
    jeudi 24 janvier 2008 10:37
  • Bonjour,

    L'intéret est au niveau de performance. Si vous utilisez votre propre HttpHandler, il traitera la requête dès la réception de la requête. Si vous utilisez une page aspx, vous passerez par le HttpHandler gérant les pages qui rajoute pas mal de traitement : chargement/sauvegarde du ViewState (qui est vide), les différents évènements (PreInit, Init, PreLoad, Load, PreRender, ...)

     

    Pour avoir une vue plus précise, vous trouverez sur la page la liste des actions obligatoires par lesquelles passe une requête :

     

    http://msdn2.microsoft.com/fr-fr/library/ms178473.aspx

     

    Dans le 15, il est indiqué que la méthode ProcessRequest est appelée sur le HttpHandler approprié. Si vous avez votre propre HttpHandler, votre code s'éxecute à ce moment. Si vous avez le HttpHandler gérant les pages aspx, voila la liste des actions effectuée par le ProcessRequest :

     

    http://msdn2.microsoft.com/fr-fr/library/ms178472.aspx

     

    Guillaume

    jeudi 24 janvier 2008 11:12
  • bonjour,

    Dans visual studio il existe les device handler (.ashx) qui font la même chose que ce qui est présenté et ont l'avantage de s'exécuter à l'appel de l'url sans les traitements inhérants aux pages aspx, sans bloquer le traitement de la page

    Ainsi :

    MonImage.url = @"~/traiteimage.ashx";

    permettra d'appeler la méthode "ProcessRequest" du fichier ashx qui écrira le flux de l'image dans le flux http à l'endroit où l'image doit s'afficher.

     

    Voici un lien vers un exemple:

    http://www.codeproject.com/KB/aspnet/AsyncBLOB.aspx

    vendredi 25 janvier 2008 12:54