Reduce Image Size in C#


Sometimes we have a requirement to reduce the image size programmatically. We can do it in C# by using System.Drawing namespace. In this article we discuss about how can we reduce the image size in C#.

Open Microsoft Visual Studio 2013 => Create new Console Application. Add new class ImgResizer as shown below.

using System;

using System.Drawing;

using System.Drawing.Drawing2D;

using System.Drawing.Imaging;

using System.IO;

 

namespace ReduceImage

{

    public class ImgResizer

    {

        private int iFileSizeInBytes;

        private string sSourcePath = string.Empty;

        private string sOutputPath = string.Empty;

 

        public ImgResizer(int sSize, string sSourcePath, string sOutputPath)

        {

            iFileSizeInBytes = sSize;

            this.sSourcePath = sSourcePath;

            this.sOutputPath = sOutputPath;

        }

 

        public void ScaleImg()

        {

            using (MemoryStream ms = new MemoryStream())

            {

                using (FileStream fs = new FileStream(sSourcePath, FileMode.Open))

                {

                    Bitmap bmp = (Bitmap)Image.FromStream(fs);

                    SaveTemporary(bmp, ms, 100);

 

                    while (ms.Length < 0.9 * iFileSizeInBytes || ms.Length > iFileSizeInBytes)

                    {

                        double scale = Math.Sqrt((double)iFileSizeInBytes / (double)ms.Length);

                        ms.SetLength(0);

                        bmp = ScaleImg(bmp, scale);

                        SaveTemporary(bmp, ms, 100);

                    }

 

                    if (bmp != null)

                        bmp.Dispose();

                    SaveImgToFile(ms);

                }

            }

        }

 

        private void SaveImgToFile(MemoryStream ms)

        {

            byte[] data = ms.ToArray();

 

            using (FileStream fs = new FileStream(sOutputPath, FileMode.Create))

            {

                fs.Write(data, 0, data.Length);

            }

        }

 

        private void SaveTemporary(Bitmap bmp, MemoryStream ms, int quality)

        {

            EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

            var codec = GetImgCodecInfo();

            var encoderParams = new EncoderParameters(1);

            encoderParams.Param[0] = qualityParam;

 

            if (codec != null)

                bmp.Save(ms, codec, encoderParams);

            else

                bmp.Save(ms, GetImgFormat());

        }

 

        public Bitmap ScaleImg(Bitmap image, double scale)

        {

            int newWidth = (int)(image.Width * scale);

            int newHeight = (int)(image.Height * scale);

 

            Bitmap result = new Bitmap(newWidth, newHeight, PixelFormat.Format24bppRgb);

            result.SetResolution(image.HorizontalResolution, image.VerticalResolution);

 

            using (Graphics g = Graphics.FromImage(result))

            {

                g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                g.CompositingQuality = CompositingQuality.HighQuality;

                g.SmoothingMode = SmoothingMode.HighQuality;

                g.PixelOffsetMode = PixelOffsetMode.HighQuality;

 

                g.DrawImage(image, 0, 0, result.Width, result.Height);

            }

            return result;

        }

 

        private ImageCodecInfo GetImgCodecInfo()

        {

            FileInfo fi = new FileInfo(sSourcePath);

 

            switch (fi.Extension)

            {

                case ".bmp": return ImageCodecInfo.GetImageEncoders()[0];

                case ".jpg":

                case ".jpeg": return ImageCodecInfo.GetImageEncoders()[1];

                case ".gif": return ImageCodecInfo.GetImageEncoders()[2];

                case ".tiff": return ImageCodecInfo.GetImageEncoders()[3];

                case ".png": return ImageCodecInfo.GetImageEncoders()[4];

                default: return null;

            }

        }

 

        private ImageFormat GetImgFormat()

        {

            FileInfo fi = new FileInfo(sSourcePath);

 

            switch (fi.Extension)

            {

                case ".jpg": return ImageFormat.Jpeg;

                case ".bmp": return ImageFormat.Bmp;

                case ".gif": return ImageFormat.Gif;

                case ".png": return ImageFormat.Png;

                case ".tiff": return ImageFormat.Tiff;

                default: return ImageFormat.Png;

            }

        }

    }

}

 

Now call ScaleImg() method of ImgResizer class as shown below.

 

namespace ReduceImage

{

    class Program

    {

        static void Main(string[] args)

        {

            string sImgPath = @"E:\img.png";

            ImgResizer resizer = new ImgResizer(15000, sImgPath, @"E:\img_new.png");

            resizer.ScaleImg();

        }

    }

}

 

As shown above we are saving reduced image as img_new.png in E drive.