views:

52

answers:

2

I return array of images ( System.Drawing.Image[] ) from database and i want to show them in datagrid or datalist .. Can any tell me how to do that ?

+1  A: 

No, there's no control that does that as far as I know.

Basically what you need to do is add a new Page (or Handler) to your solution, and from that page, you do a Response.BinaryWrite to write the image directly to the response. Then in your main page, you link an image to that new page kind of like <img src="MyImage.aspx?Id=1"/>

These links should provide you a good start.

http://odetocode.com/articles/172.aspx

http://www.4guysfromrolla.com/articles/120606-1.aspx

Greg
i already use this way but i always ask if i have a gridView that will show 10 images in the page .. is mean u need to do 10 connections to the server to get each image :( ?
Space Cracker
You are correct. That's why you should use a handler instead of a page (less resources needed) and url rewriting to serve the images on disk without even entering the ASP.Net pipe (see my answer)
marapet
thanks marapet.
Space Cracker
+2  A: 

If the images are fairly small, you could send them Base64 encoded with the markup of the web page.

Please note: This is only a demonstration in order to show that it is possible to do this, I don't think this should be done on a real web site.

In reality, you should:

  • consider writing those images to disk and serving them as regular images and with proper caching headers without hitting the database each time.
  • implement a handler which checks first if the image exists already on disk, and only retrieve it from the db if needed (which will only be the first time a image is asked for).
  • use url rewriting, and only pass the image urls which do not correspond to a image on disk to the handler. This is faster than passing all request through the ASP.Net pipe. IIRF does that perfectly well.

This said, here's the demonstration with base64 encoded images. Add a Repeater to your page:

<asp:Repeater ID="ImageRepeater" runat="server">
<ItemTemplate>
    <asp:Literal ID="ltImage" runat="server"><img src="data:image/jpg;base64,{0}" alt="" /></asp:Literal>
</ItemTemplate>
</asp:Repeater>

In your codebehind, bind the images to the repeater:

private void BindImages(System.Drawing.Image[] images)
{
    this.ImageRepeater.DataSource = images;
    this.ImageRepeater.ItemDataBound += delegate(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
        {
            System.Drawing.Image img = e.Item.DataItem as System.Drawing.Image;
            Literal lt = e.Item.FindControl("ltImage") as Literal;

            lt.Text = string.Format(lt.Text, ImageToBase64(img, ImageFormat.Jpeg));
        }
    };
    this.ImageRepeater.DataBind();
}

private string ImageToBase64(System.Drawing.Image image,  System.Drawing.Imaging.ImageFormat format)
{ 
    using (MemoryStream ms = new MemoryStream())
    {
        // Convert Image to byte[]
        image.Save(ms, format);
        byte[] imageBytes = ms.ToArray();

        // Convert byte[] to Base64 String
        string base64String = Convert.ToBase64String(imageBytes);
        return base64String;
    }
}

You may want to disable Viewstate...

Thanks to dailycoding.com and Dean Edwards for code bits.

marapet