0

I am resizing image on website using ImageHandler.ashx which re-sizes image on fly. but with loss of quality.

How can i improve this code to improve quality of image. Image with this code comes slightly pixelated.

I use following line of code to show images

imgBanner.ImageUrl = "../ImageHandler.ashx?h=108&w=162&file=../images/ImageName.jpg

Following is the code for handler

<%@ WebHandler Language="C#" Class="ImageHandler" %>

using System;
using System.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

public class ImageHandler : IHttpHandler {

    public void ProcessRequest(HttpContext context)
    {
        // for new height of image
        int h = int.Parse(context.Request.QueryString["h"].ToString());
        // for new width of image
        int w = int.Parse(context.Request.QueryString["w"].ToString());
        // for  image file name
        string file = context.Request.QueryString["file"].ToString();

        // Path of image folder where images files are placed
        string filePath = context.Server.MapPath("~/images/" + file);

        // Resize proccess
        using (System.Drawing.Image img = System.Drawing.Image.FromFile(filePath))
        {
            Bitmap objBmp = new Bitmap(img, w, h);
            string extension = Path.GetExtension(filePath);
            MemoryStream ms;
            byte[] bmpBytes;
            switch (extension.ToLower())
            {
                case ".jpg":
                case ".jpeg":
                    ms = new MemoryStream();
                    objBmp.Save(ms, ImageFormat.Jpeg);
                    bmpBytes = ms.GetBuffer();
                    context.Response.ContentType = "image/jpeg";
                    context.Response.BinaryWrite(bmpBytes);
                    objBmp.Dispose();
                    ms.Close();
                    context.Response.End();
                    break;
                case ".png":
                    ms = new MemoryStream();
                    objBmp.Save(ms, ImageFormat.Png);
                    bmpBytes = ms.GetBuffer();
                    context.Response.ContentType = "image/png";
                    context.Response.BinaryWrite(bmpBytes);
                    objBmp.Dispose();
                    ms.Close();
                    context.Response.End();
                    break;
                case ".gif":
                    ms = new MemoryStream();
                    objBmp.Save(ms, ImageFormat.Gif);
                    bmpBytes = ms.GetBuffer();
                    context.Response.ContentType = "image/png";
                    context.Response.BinaryWrite(bmpBytes);
                    objBmp.Dispose();
                    ms.Close();
                    context.Response.End();
                    break;

            }
            img.Dispose();
        }
    }

    public bool IsReusable {
        get {
            return false;
        }
    }

}
Learning
  • 19,469
  • 39
  • 180
  • 373
  • 1
    You cannot just resize and expect your image to not loose quality .. Take a look at this thread for some suggestions http://stackoverflow.com/questions/11137979/image-resizing-using-c-sharp – G-Man Dec 19 '13 at 10:39
  • and here is another one http://stackoverflow.com/questions/249587/high-quality-image-scaling-c-sharp – G-Man Dec 19 '13 at 10:42
  • Is their a possibility that this code can be improved... but adding quality value... – Learning Dec 19 '13 at 10:53

1 Answers1

1

Is their a possibility that this code can be improved... but adding quality value..

Try to keep the aspect ratio of the original image. The resized image should fit into the specified width and height, but also keep the aspect ratio.

You could also try to different values of InterpolationMode.

My image resize handlers usually contain a variation of this code:

protected Image Resize(Image img, int resizedW, int resizedH)
{
    Bitmap bmp = new Bitmap(resizedW, resizedH);
    Graphics graphic = Graphics.FromImage((Image)bmp);
    graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
    graphic.DrawImage(img, 0, 0, resizedW, resizedH);
    graphic.Dispose();
    return (Image)bmp;
}

Edit based on comment:
Almost identically to your code:

    Image pic = Resize(img, w, h);
    MemoryStream ms = new MemoryStream(); // better use a using statement
    pic.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
   // continue with your code to write to the output stream
citronas
  • 19,035
  • 27
  • 96
  • 164