1

I found a nice code to down size image on server, to avoid bad image rendering by different browser. This code is for MVC application.

I have no experience in C# would like to know what do I need to change to make this code work in webforms.

<img src="@Url.Action("ResizeImage", "Controller", new { urlImage = "<url_image>", width = 35 })" />

public ActionResult ResizeImage(string imageUrl, int width)
{
    WebImage wImage = new WebImage(imageUrl);
    wImage = WebImageExtension.Resize(wImage, width);
    return File(wImage.GetBytes(), "image/png");
}

public static class WebImageExtension
{
    private static readonly IDictionary<string, ImageFormat> TransparencyFormats =
        new Dictionary<string, ImageFormat>(StringComparer.OrdinalIgnoreCase) { { "png", ImageFormat.Png }, { "gif", ImageFormat.Gif } };

    public static WebImage Resize(this WebImage image, int width)
    {
        double aspectRatio = (double)image.Width / image.Height;
        var height = Convert.ToInt32(width / aspectRatio);

        ImageFormat format;

        if (!TransparencyFormats.TryGetValue(image.ImageFormat.ToLower(), out format))
        {
            return image.Resize(width, height);
        }

        using (Image resizedImage = new Bitmap(width, height))
        {
            using (var source = new Bitmap(new MemoryStream(image.GetBytes())))
            {
                using (Graphics g = Graphics.FromImage(resizedImage))
                {
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.DrawImage(source, 0, 0, width, height);
                }
            }

            using (var ms = new MemoryStream())
            {
                resizedImage.Save(ms, format);
                return new WebImage(ms.ToArray());
            }
        }
    }
}

UPDATE:

I use this code to resize images

public static void ResizeImageFreeSize(string OriginalFile, string NewFile, int MinWidth, int MinHeight, string FileExtension)
{
var NewHeight = MinHeight;
var NewWidth = MinWidth;
// var OriginalImage = System.Drawing.Image.FromFile(OriginalFile); // THis statlement alon with generate error as file is locked so -->GDI+ keeps a lock on files from which an image was contructed.  To avoid the lock, construct the image from a MemorySteam:

MemoryStream ms = new MemoryStream(File.ReadAllBytes(OriginalFile));
var OriginalImage = System.Drawing.Image.FromStream(ms);

if (OriginalImage.Width < MinWidth || OriginalImage.Height < MinHeight)
    throw new Exception(String.Format("Invalid Image Dimensions, please upload an image with minmum dimensions of {0}x{1}px", MinWidth.ToString(), MinHeight.ToString()));

// If the image dimensions are the same then make the new dimensions the largest of the two mins.
if (OriginalImage.Height == OriginalImage.Width)
    NewWidth = NewHeight = (MinWidth > MinHeight) ? MinWidth : MinHeight;
else
{
    if (MinWidth > MinHeight)
        NewHeight = (int)(OriginalImage.Height * ((float)MinWidth / (float)OriginalImage.Width));
    else
        NewWidth = (int)(OriginalImage.Width * ((float)MinHeight / (float)OriginalImage.Height));
}

// Just resample the Original Image into a new Bitmap
var ResizedBitmap = new System.Drawing.Bitmap(OriginalImage, NewWidth, NewHeight);

// Saves the new bitmap in the same format as it's source image
FileExtension = FileExtension.ToLower().Replace(".", "");

ImageFormat Format = null;
switch (FileExtension)
{
    case "jpg":
        Format = ImageFormat.Jpeg;

        Encoder quality = Encoder.Quality;
        var ratio = new EncoderParameter(quality, 100L);
        var codecParams = new EncoderParameters(1);
        codecParams.Param[0] = ratio;
        // NewImage.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams);
        ResizedBitmap.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams);
        break;
    case "gif":
        Format = ImageFormat.Gif;
        ResizedBitmap.Save(NewFile, Format);
        break;
    case "png":
        Format = ImageFormat.Png;
        ResizedBitmap.Save(NewFile, Format);
        break;
    default:
        Format = ImageFormat.Png;
        ResizedBitmap.Save(NewFile, Format);
        break;
}

//  ResizedBitmap.Save(NewFile, Format);


// Clear handle to original file so that we can overwrite it if necessary
OriginalImage.Dispose();
ResizedBitmap.Dispose();
}
0

1 Answer 1

1

You can have a HttpHandler for this in C#,

namespace CMSN.Software.Tutorials.HowToDynamicallyResizeImages
{
    public class DynamicImage : IHttpHandler
    {
        /// <summary>
        /// Default cache duration
        /// </summary>
        private static readonly TimeSpan CacheDuration = TimeSpan.FromDays(30);

        /// <summary>
        /// Gets a value indicating whether another request can use the 
        /// <see cref="T:System.Web.IHttpHandler"/> instance.
        /// </summary>
        /// <returns>
        /// true if the <see cref="T:System.Web.IHttpHandler"/> instance is reusable; otherwise, false.
        /// </returns>
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Enables processing of HTTP Web requests by a custom HttpHandler that implements the 
        /// <see cref="T:System.Web.IHttpHandler"/> interface.
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpContext"/> object that provides references to the 

        /// intrinsic server objects (for example, Request, Response, Session, and Server) 
        /// used to service HTTP requests.
        /// </param>
        public void ProcessRequest(HttpContext context)
        {
            string cacheKeyName = context.Request.Url.PathAndQuery;
            string imagePath = context.Server.MapPath(context.Request.Url.LocalPath);
            string imageExtention = Path.GetExtension(imagePath);
            string contentType = string.Empty;
            byte[] imageFileContent;
            ImageFormat imageFormat = null;

            switch (imageExtention)
            {
                case ".png":
                    imageFormat = ImageFormat.Png;
                    contentType = "image/png";
                    break;
                case ".jpg":
                case ".jpeg":
                case ".jpe":
                    imageFormat = ImageFormat.Jpeg;
                    contentType = "image/jpeg";
                    break;
                case ".bmp":
                    imageFormat = ImageFormat.Bmp;
                    contentType = "image/bmp";
                    break;
                case ".gif":
                    imageFormat = ImageFormat.Gif;
                    contentType = "image/gif";
                    break;
                default:
                    break;
            }

            context.Response.ContentType = contentType;

            if (context.Cache[CacheKey(cacheKeyName)] != null)
            {
                imageFileContent = context.Cache[CacheKey(cacheKeyName)] as byte[];
            }
            else
            {
                int imageWidth = 0;
                int imageHeight = 0;

                if (!string.IsNullOrEmpty(context.Request["w"]))
                {
                    if (!int.TryParse(context.Request["w"], out imageWidth))
                    {
                        imageWidth = 0;
                    } 
                }

                if (!string.IsNullOrEmpty(context.Request["h"]))
                {
                    if (!int.TryParse(context.Request["h"], out imageHeight))
                    {
                        imageHeight = 0;
                    }
                }

                Image originalImage;

                if (File.Exists(imagePath))
                {
                    originalImage = Image.FromFile(imagePath);
                }
                else
                {
                    originalImage = new Bitmap(100, 100);
                }

                if (imageWidth > 0 || imageHeight > 0)
                {
                    if (imageHeight == 0 && imageWidth > 0)
                    {
                        imageHeight = originalImage.Height * imageWidth / originalImage.Width;
                    }

                    if (imageWidth == 0 && imageHeight > 0)
                    {
                        imageWidth = originalImage.Width * imageHeight / originalImage.Height;
                    }
                }
                else
                {
                    imageHeight = originalImage.Height;
                    imageWidth = originalImage.Width;
                }

                using (Bitmap newImage = new Bitmap(originalImage, imageWidth, imageHeight))
                {
                    Graphics generatedImage = Graphics.FromImage(newImage);
                    generatedImage.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    generatedImage.SmoothingMode = SmoothingMode.AntiAlias;
                    generatedImage.CompositingQuality = CompositingQuality.HighQuality;
                    generatedImage.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);

                    // make a memory stream to work with the image bytes
                    using (MemoryStream imageStream = new MemoryStream())
                    {
                        // put the image into the memory stream
                        newImage.Save(imageStream, imageFormat);

                        // make byte array the same size as the image
                        byte[] imageContent = new byte[imageStream.Length];

                        // rewind the memory stream
                        imageStream.Position = 0;

                        // load the byte array with the image
                        imageStream.Read(imageContent, 0, (int)imageStream.Length);

                        // return byte array to caller with image type
                        imageFileContent = imageContent;

                        using (CacheDependency dependency = new CacheDependency(imagePath))
                        {
                            context.Cache.Insert(
                            CacheKey(cacheKeyName),
                            imageContent,
                            dependency,
                            System.Web.Caching.Cache.NoAbsoluteExpiration,
                            CacheDuration);
                        }
                    }
                }

                originalImage.Dispose();
            }

            SetResponseCache(context.Response, new string[1] { imagePath });
            context.Response.BinaryWrite(imageFileContent);
        }

        /// <summary>
        /// Generate unique Cache key.
        /// </summary>
        /// <param name="key">The cache key.</param>
        /// <returns>Generated unique Cache key</returns>
        protected static string CacheKey(string key)
        {
            return "DynamicImage." + key;
        }

        /// <summary>
        /// Sets the response cache.
        /// </summary>
        /// <param name="response">The response.</param>
        /// <param name="files">The files.</param>
        protected static void SetResponseCache(HttpResponse response, string[] files)
        {
            response.AddFileDependencies(files);
            HttpCachePolicy browserCache = response.Cache;
            DateTime modifiedTime = DateTime.Now;
            browserCache.SetCacheability(HttpCacheability.ServerAndPrivate);
            browserCache.VaryByParams["w"] = true;
            browserCache.VaryByParams["h"] = true;
            browserCache.VaryByParams["v"] = true;
            browserCache.SetOmitVaryStar(true);
            browserCache.SetExpires(modifiedTime.AddDays(7));
            browserCache.SetValidUntilExpires(true);
            browserCache.SetLastModified(modifiedTime);
            browserCache.SetETagFromFileDependencies();
            browserCache.SetLastModifiedFromFileDependencies();
        }
    }
}

Web.config

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpHandlers>
      <add verb="*" path="*.png,*.jpg,*.jpeg,*.gif,*.bmp" type="CMSN.Software.Tutorials.HowToDynamicallyResizeImages.DynamicImage,HowToDynamicallyResizeImages"/>
    </httpHandlers>
  </system.web>
  <system.webServer>
    <handlers>
      <add verb="*" path="*.png,*.jpg,*.jpeg,*.gif,*.bmp" name="DynamicImage" type="CMSN.Software.Tutorials.HowToDynamicallyResizeImages.DynamicImage,HowToDynamicallyResizeImages"/>
    </handlers>
    <validation validateIntegratedModeConfiguration="false"/>
  </system.webServer>
</configuration>

Usage,

http://localhost/Images/xxxxxxxx.png?w=300&h=149

If you want to see the complete guide for this, please follow the following URL.

http://tutorials.cmsnsoftware.com/2011/09/how-to-dynamically-resize-images.html

Sign up to request clarification or add additional context in comments.

4 Comments

Look good, How can i call use it with <asp:Image ID="imgArticleImage" ImageUrl='<%# getImage(Eval("NewsImage")) %>' runat="server" /> ` protected String getImage(object img) { string imgPath = img.ToString(); imgPath = "../images/NewsImages/" + imgPath; return imgPath; }`
@KnowledgeSeeker, This is how you use it <asp:Image ID="imgArticleImage" ImageUrl='http://localhost/Images/xxxxxxxx.png?w=300&h=149' runat="server" />
Thanks i am able to work with, I just notice that quality of image is not good when downsizing...
I will update my question & put some code which i use to resize image which gives me atleast good quality. I am not sure if it can be intergrated with your dynamic resize code. Just give me a minute & i hope you can improve it as this is a very nice thing you have done.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.