BCartolo
BCartolo

Reputation: 719

Extend Image server control to specify image dimensions automatically

The browser would render a webpage faster if it knows the images dimensions. But how can I assign the Width and Height in ASP.NET automatically?

I can do a server control extending Image that would query the image size using GDI+ and assign those values to its own Width and Height properties.

But there are several things that worries me and would like to hear opinions:

Of course I have an idea of how to do all that I mentioned, but I wanted to hear some thoughts.

http://code.google.com/speed/page-speed/docs/rendering.html#SpecifyImageDimensions

EDIT: This is what I have so far:

[ToolboxData("<{0}:AutoSizeImage runat=server></{0}:AutoSizeImage>")]
public class AutoSizeImage : Image
{
    protected override void OnPreRender(EventArgs e)
    {
        if (Width.Value + Height.Value == 0)
        {
            if (IsLocal(ImageUrl))
            {
                using (System.Drawing.Image img = System.Drawing.Image.FromFile(Context.Server.MapPath(ImageUrl)))
                {
                    Width = img.Width;
                    Height = img.Height;
                }
            }
            else
            {
                System.Net.WebRequest request = System.Net.WebRequest.Create(ImageUrl);
                using (System.Net.WebResponse response = request.GetResponse())
                using (System.IO.Stream responseStream = response.GetResponseStream())
                using (System.Drawing.Image img = System.Drawing.Image.FromStream(responseStream))
                {
                    Width = img.Width;
                    Height = img.Height;
                }
            }
        }
        base.OnPreRender(e);
    }
    private bool IsLocal(string p)
    {
        return !(p.StartsWith("http://") || p.StartsWith("https://") || p.StartsWith("ftp://"));
    }
}

It works beautifully, but I need to implement cache now. I want to cache the output of this control for each value of ImageUrl, that is, I want the OnPreRender method to be called once for each image. Is that possible?

Upvotes: 1

Views: 461

Answers (3)

BCartolo
BCartolo

Reputation: 719

I am going to use Image Optimization Framework that generates sprites and writes the image width and height so no need to reinvent the wheel.

https://web.archive.org/web/20211020150102/https://www.4guysfromrolla.com/articles/101310-1.aspx

Upvotes: 0

SalataLuc
SalataLuc

Reputation: 410

  1. If the size of images will change foreach user that are using the app, then you will have to use Session or Cookie. Otherwise, if the size of images will not change (always the same size, user independent), then maybe better you use Cache. Which method should I use to query the image size? The constructor or another method (OnInit, OnPreRender, etc, etc)?

  2. In PreRender, because at this time all your controls are already created. This is the best moment to set the properties of your controls.

  3. In your scope, I think so. The GDI+ is optimized for it.

  4. Remote images?

Upvotes: 1

AlbertVo
AlbertVo

Reputation: 772

If you are going to be querying the image size on the fly, you might end up making things slower. Of course it all depends on how your application works.

If I were to try to do something similar, I would get the image dimensions at the time when the image is uploaded. (or when it was created using a filesystem watcher). I would then store this information in a database and then cache against the database.

Upvotes: 1

Related Questions