views:

163

answers:

2

I have a curious problem with IE, IIS 6.0 dynamic PNG files and I am baffled as to how to fix..

Snippet from Helper (this returns the URL to the view for requesting the images from my Controller.

string url = LinkBuilder.BuildUrlFromExpression(helper.ViewContext.RequestContext, helper.RouteCollection, c => c.FixHeight(ir.Filename, ir.AltText, "FFFFFF")); url = url.Replace("&", "&"); sb.Append(string.Format("<removed id=\"TheImage\" src=\"{0}\" alt=\"\" />", url)+Environment.NewLine);

This produces a piece of html as follows:- img id="TheImage" src="/ImgText/FixHeight?sFile=Images%2FUser%2FJulianGuppy%2FMediums%2Fconservatory.jpg&backgroundColour=FFFFFF" alt="" /

brackets missing because i cant post an image... even though I dont want to post an image I jsut want to post the markup... sigh

Snippet from Controller ImgTextController

    /// <summary>
    /// This function fixes the height of the image
    /// </summary>
    /// <param name="sFile"></param>
    /// <param name="alternateText"></param>
    /// <param name="backgroundColour"></param>
    /// <returns></returns>
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult FixHeight(string sFile, string alternateText, string backgroundColour)
    {
        #region File
        if (string.IsNullOrEmpty(sFile))
        {
            return new ImgTextResult();
        }
        // MVC specific change to prepend the new directory
        if (sFile.IndexOf("Content") == -1)
        {
            sFile = "~/Content/" + sFile;
        }

        // open the file
        System.Drawing.Image img;
        try
        {
            img = System.Drawing.Image.FromFile(Server.MapPath(sFile));
        }
        catch
        {
            img = null;
        }
        // did we fail?
        if (img == null)
        {
            return new ImgTextResult();
        }
        #endregion File

        #region Width
        // Sort out the width from the image passed to me
        Int32 nWidth = img.Width;
        #endregion Width

        #region Height
        Int32 nHeight = img.Height;
        #endregion Height

        // What is the ideal height given a width of 2100 this should be 1400.
        var nIdealHeight = (int)(nWidth / 1.40920096852);
        // So is the actual height of the image already greater than the ideal height?
        Int32 nSplit;

        if (nIdealHeight < nHeight)
        {
            // Yes, do nothing, well i need to return the iamge...
            nSplit = 0;
        }
        else
        {
            // rob wants to not show the white at the top or bottom, so if we were to crop the image how would be do it
            // 1. Calculate what the width should be If we dont adjust the heigt
            var newIdealWidth = (int)(nHeight * 1.40920096852);

            // 2. This newIdealWidth should be smaller than the existing width... so work out the split on that
            Int32 newSplit = (nWidth - newIdealWidth) / 2;

            // 3. Now recrop the image using 0-nHeight as the height (i.e. full height)
            // but crop the sides so that its the correct aspect ration
            var newRect = new Rectangle(newSplit, 0, newIdealWidth, nHeight);

            img = CropImage(img, newRect);
            nHeight = img.Height;
            nWidth = img.Width;
            nSplit = 0;
        }

        // No, so I want to place this image on a larger canvas and we do this by Creating a new image to be the size that we want
        System.Drawing.Image canvas = new Bitmap(nWidth, nIdealHeight, PixelFormat.Format24bppRgb);
        Graphics g = Graphics.FromImage(canvas);

        #region Color
        // Whilst we can set the background colour we shall default to white
        if (string.IsNullOrEmpty(backgroundColour))
        {
            backgroundColour = "FFFFFF";
        }
        Color bc = ColorTranslator.FromHtml("#" + backgroundColour);
        #endregion Color

        // Filling the background (which gives us our broder)
        Brush backgroundBrush = new SolidBrush(bc);
        g.FillRectangle(backgroundBrush, -1, -1, nWidth + 1, nIdealHeight + 1);

        // draw the image at the position
        var rect = new Rectangle(0, nSplit, nWidth, nHeight);
        g.DrawImage(img, rect);

        return new ImgTextResult { Image = canvas, ImageFormat = ImageFormat.Png };
    }

My ImgTextResult is a class that returns an Action result for me but embedding the image from a memory stream into the response.outputstream.

snippet from my ImageResults

    /// <summary>
    /// Execute the result
    /// </summary>
    /// <param name="context"></param>
    public override void ExecuteResult(ControllerContext context)
    {
        // output
        context.HttpContext.Response.Clear();
        context.HttpContext.Response.ContentType = "image/png";

        try
        {
            var memStream = new MemoryStream();
            Image.Save(memStream, ImageFormat.Png);
            context.HttpContext.Response.BinaryWrite(memStream.ToArray());
            context.HttpContext.Response.Flush();
            context.HttpContext.Response.Close();
            memStream.Dispose();
            Image.Dispose();
        }
        catch (Exception ex)
        {
            string a = ex.Message;
        }
    }

Now all of this works locally and lovely, and indeed all of this works on my production server

BUT Only for Firefox, Safari, Chrome (and other browsers) IE has a fit and decides that it either wont display the image or it does display the image after approx 154seconds of waiting.....

I have made sure my HTML is XHTML compliant, I have made sure I am getting no Routing errors or crashes in my event log on the server....

Now obviously I have been a muppet and have done something wrong... but what I cant fathom is why in development all works fine, and in production all non IE browsers also work fine, but IE 8 using IIS 6.0 production server is having some kind of problem in returning this PNG and I dont have an error to trace... so what I am looking for is guidance as to how I can debug this problem.

A: 

Looks like it might be time to install Fiddler or HttpWatch and find out what is going on.

mrjoltcola
Fiddler wouldn't work on my vista install, i will have a look at httpwatch though.... i need all the help I can get...
julian guppy
Got fiddler to work on my vista dev box finally. And wow - if i use IE (whilst fiddler is in the middle) ie behaves impeccably. with images downloading and showing inside 1/2 second.... take away fiddler and the images stop showing.... what the hell is IE 8 complaining about or waiting for when showing these images....? and why do all other browsers just work...? Incredibly frustrating...
julian guppy
A: 

Well, what I wanted to do was to convert my images (jpg, bmp, etc... and return them as png) - however. Although all other browsers would accept the encoding and display them fine, IE decided to hide the png image (after partially displaying it) because it thought it wasn't a PNG image. (Even though it was) So I gave up with the conversion methods and just returned the image in its original format. ---

if anybody comes up with a way of reliably converting any image format into png so that I can return it dynamically from a memory stream, then please do let me know....

So I am closing this for now as IE has won this battle -

I wish IE would just sod off and die. I hate IE so much. Seriously it just sucks the sweat of a dead mans balls.

julian guppy