tags:

views:

47

answers:

2

I have a script which resizes images, I did not write this script, nor do I know any ASP.NET, but I have been assigned the task of fixing an issue with it!

The problem is, the resulting image from the resize appears to be of less quality than the upload, even if the file uploaded is already set to the correct size.

Uploaded image - http://climatechange.cbi.org.uk/uploaded/whatevhomep.jpg Resized image - http://climatechange.cbi.org.uk/ext_pages/resizeimage.aspx?img=/uploaded/whatevhomep.jpg&w=500

The script that is doing the resizing is as follows, any idea how to correct the issue?

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

public partial class ext_pages_resizeImage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //Read in the image filename to create a thumbnail of
        String imageUrl = "";

        try
        {   imageUrl = Request.QueryString["img"].ToString();
        }catch(Exception imgEx){}

        //Read in the width and height
        int thumbWidth = 0;
        int imageOrigHeight = 0;
        int imageOrigWidth = 0;

        try
        {
            thumbWidth = Convert.ToInt32(Request.QueryString["w"].ToString());
        }catch(Exception imgHEx)
        {
            thumbWidth = Convert.ToInt32(Request.QueryString["amp;w"]);
        }


        if (!System.IO.File.Exists(Server.MapPath(imageUrl)))
            Response.End();

        System.IO.FileInfo fileDetails = new System.IO.FileInfo(Server.MapPath(imageUrl));

        System.Drawing.Image fullSizeImg; 
        fullSizeImg = System.Drawing.Image.FromFile(Server.MapPath(imageUrl));

        imageOrigHeight = fullSizeImg.Height;
        imageOrigWidth = fullSizeImg.Width;

        Decimal sizeRatio = ((Decimal)imageOrigHeight / imageOrigWidth);
        int thumbHeight = Decimal.ToInt32(sizeRatio * thumbWidth);

        if (thumbHeight <= 0 || thumbWidth <= 0)
        {
            pageMisc oPageMisc = new pageMisc();

            oPageMisc.sendMail("[email protected]", "CBI CC Image Errors", "Width: " + thumbWidth.ToString() + ", Height: " + thumbHeight.ToString());
        }

        Bitmap bmp = new Bitmap(thumbWidth, thumbHeight);

        System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(bmp);
        gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

        System.Drawing.Rectangle rectDestination = new System.Drawing.Rectangle(0, 0, thumbWidth, thumbHeight);
        gr.DrawImage(fullSizeImg, rectDestination, 0, 0, imageOrigWidth, imageOrigHeight, GraphicsUnit.Pixel);

        switch (fileDetails.Extension.ToUpper())
        {
            case ".JPG":
                Response.ContentType = "image/jpeg";
                break;
            case ".GIF":
                Response.ContentType = "image/gif";
                break;
        }

        //Do we need to create a thumbnail?
        if (thumbHeight > 0 && thumbWidth > 0)
        {
            System.Drawing.Image.GetThumbnailImageAbort dummyCallBack;
            dummyCallBack = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);

            System.Drawing.Image thumbNailImg;
            thumbNailImg = fullSizeImg.GetThumbnailImage(thumbWidth, thumbHeight, dummyCallBack, IntPtr.Zero);

            switch (fileDetails.Extension.ToUpper())
            {
                case ".JPG":
                    bmp.Save(Response.OutputStream, ImageFormat.Jpeg);
                    break;
                case ".GIF":
                    bmp.Save(Response.OutputStream, ImageFormat.Gif);
                    break;
            }

            //Clean up / Dispose...
            thumbNailImg.Dispose();
        }
        else
        {
            switch (fileDetails.Extension.ToUpper())
            {
                case ".JPG":
                    fullSizeImg.Save(Response.OutputStream, ImageFormat.Jpeg);
                    break;
                case ".GIF":
                    fullSizeImg.Save(Response.OutputStream, ImageFormat.Gif);
                    break;
            }
        }

        //Clean up / Dispose...
        fullSizeImg.Dispose();
        bmp.Dispose();
    }

    public static bool ThumbnailCallback()
    {
        return false;
    }

}

UPDATE SHOWING ERROR MESSAGE

Compiler Error Message: CS0103: The name 'GetEncoder' does not exist in the current context

Source Error:


Line 109:                    var codecParams = new EncoderParameters(1);
Line 110:                    codecParams.Param[0] = ratio;
Line 111:                    fullSizeImg.Save(Response.OutputStream, GetEncoder(ImageFormat.Jpeg), codecParams);
Line 112:                    break; 
Line 113:                case ".GIF":

Line: 111 
+1  A: 

You need to specify a higher quality when saving as JPEG. Replace you JPEG case with the following:

case ".JPG": 
    Encoder quality = Encoder.Quality;
    var ratio = new EncoderParameter(quality, 80L);
    var codecParams = new EncoderParameters(1);
    codecParams.Param[0] = ratio;
    fullSizeImg.Save(Response.OutputStream, GetEncoder(ImageFormat.Jpeg), codecParams);
    break; 

And add this function:

    private ImageCodecInfo GetEncoder(ImageFormat format)
    {
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
        foreach (ImageCodecInfo codec in codecs)
            if (codec.FormatID == format.Guid)
                return codec;
        return null;
    }

Something similar is probably needed for GIF.

RedFilter
Thanks for your response. Forgive my lack of understanding, but where in the code would I insert that to get the full quality image? Thanks!
Probocop
@probocop: see my edit - replace the case statement with mine for JPG
RedFilter
@RedFilter - Hmm I just tried that and it appears to be throwing an error, any idea why that would be? I Replaced the case for JPG and FTP'd the file back up to the server.
Probocop
Without seeing the error message, no, I couldn't tell you.
RedFilter
@RedFilter - I managed to get the error message, I've updated my original post with it. Thanks alot for the help!
Probocop
@Probocop: sorry, missing function. I have added it in.
RedFilter
A: 

Try to use GetThumbnailImage function:

System.Drawing.Image.GetThumbnailImageAbort dummyCallBack
       = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
System.Drawing.Image thumbNailImg = fullSizeImg.GetThumbnailImage(
                    nWidth, 
                    nHeight,
                    dummyCallBack, 
                    IntPtr.Zero);

ThumnailCallback function:

    //this function is reqd for thumbnail creation
    protected bool ThumbnailCallback()
    {
        return false;
    }
Minh Nguyen