Reducing JPEG Picture Quality using C#

Learn how to create an application that reduces the quality of JPEG pictures from a folder and then puts the new pictures into another folder.

Changing the picture quality of a JPEG file In this C# programming tutorial we’re going to create a quite useful little application – one that takes every JPEG picture in a folder and changes its quality to a desired rate, which obviously reduces the size of the JPEG file. Thus, aside from using an encoder to reduce the quality of the picture, you’ll also learn how to scan a folder for files of a certain type, and put them in a ListBox.

Designing the application Fire up Visual Studio 2005 and start a new C# Windows Application. On it draw two buttons – btnOpen and btnReduce – they will be used to select the folder where you want to look for the pictures to be modified, and the folder where the modified pictures will be stored. The big control on this page is the ListBox control named lstPhotos, it is where the list of files to be reduced in quality will be stored. Then there’s numQual – a NumericUpDown with values of 1 to 100 – which will define the quality to which we want the pictures reduced. Finally the last control to add to the form is prgReduce – a ProgressBar that keeps track of the progress made in resizing all the files. You will see that the progress bar works quite fine, even though we’re not going to use a separate thread for the picture reducing code.

Remember when I said we added our last component to the form? I lied. We still need the two dialogs that fire up when the btnOpen and btnReduce are clicked. They allow the user to select the folder where they want the files to be picked up from, and where the new ones are to be dropped. These two are FolderBrowserDialogs and are named as follows:

The code behind the application Since we’re going to be working with graphic files and directories, the following two using statements are appropriate:

using System.IO;

using System.Drawing.Imaging;

Our code is divided into two: the scanning of the folder from where we pick up the pictures, and the quality reducing and file saving code. The first part happens inside the click event of btnOpen:

private void btnOpen_Click(object sender, EventArgs e)

{

    if (fbdOpen.ShowDialog() == DialogResult.OK)

    {

        // Clear any previous items in the list

        lstPhotos.Items.Clear();

        // Run a loop through all the files in the directory at the selected path

        foreach(string Filename in Directory.GetFiles(fbdOpen.SelectedPath))

        {

            // We'll create a new FileInfo object from the file path

            FileInfo fiPicture = new FileInfo(Filename);

            // If it's a JPEG file

            if (fiPicture.Extension.ToLower() == ".jpeg" || fiPicture.Extension.ToLower() == ".jpg")

            {

                // Add it to the list of files

                lstPhotos.Items.Add(Filename);

            }

        }

    }

    // We want the ProgressBar to have the same maximum value as the number of pictures to resize

    prgReduce.Maximum = lstPhotos.Items.Count;

}

Being commented, the code should be pretty easy to figure out. All we do is loop through the files in the directory and if they have the jpeg/jpg extension, we add them to the list.
So let’s move on to the click event of btnReduce, where the second and final piece of code exists, which is more interesting since its the actual code that reduces the quality:

private void btnReduce_Click(object sender, EventArgs e)

{

    // Reset the progress bar

    prgReduce.Value = 0;

    // Show the FolderBrowserDialog where the user selects where to save the files

    if (fbdSave.ShowDialog() == DialogResult.OK)

    {

        // We will store the correct image codec in this object

        ImageCodecInfo iciJpegCodec = null;

        // This will specify the image quality to the encoder

        EncoderParameter epQuality = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (int)numQual.Value);

        // Get all image codecs that are available

        ImageCodecInfo[] iciCodecs = ImageCodecInfo.GetImageEncoders();

        // Store the quality parameter in the list of encoder parameters

        EncoderParameters epParameters = new EncoderParameters(1);

        epParameters.Param[0] = epQuality;

 

        // Loop through all the image codecs

        for (int i = 0; i < iciCodecs.Length; i++)

        {

            // Until the one that we are interested in is found, which is image/jpeg

            if (iciCodecs[i].MimeType == "image/jpeg")

            {

                iciJpegCodec = iciCodecs[i];

                break;

            }

        }

 

        // Loop through the files in the list

        foreach (string strFile in lstPhotos.Items)

        {

            // Take another step on the progress bar

            prgReduce.PerformStep();

 

            // Create a new Image object from the current file

            Image newImage = Image.FromFile(strFile);

 

            // Get the file information again, this time we want to find out the extension

            FileInfo fiPicture = new FileInfo(strFile);

            // Save the new file at the selected path with the specified encoder parameters, and reuse the same file name

            newImage.Save(fbdSave.SelectedPath + "\\" + fiPicture.Name, iciJpegCodec, epParameters);

        }

    }

    // Open the folder containing the new items

    System.Diagnostics.Process.Start(fbdSave.SelectedPath.ToString());

}

What this code does is to retrieve the correct image codec for JPEG files; we will need it in order to change the quality of the file. The code can be improved nicely if put into its separate class and into its separate thread. It would also help the progress bar act more smoothly.

Compile the application and run. You just built yourself a little JPEG processing application:

Nathan Pakovskie is an esteemed senior developer and educator in the tech community, best known for his contributions to Geekpedia.com. With a passion for coding and a knack for simplifying complex tech concepts, Nathan has authored several popular tutorials on C# programming, ranging from basic operations to advanced coding techniques. His articles, often characterized by clarity and precision, serve as invaluable resources for both novice and experienced programmers. Beyond his technical expertise, Nathan is an advocate for continuous learning and enjoys exploring emerging technologies in AI and software development. When he’s not coding or writing, Nathan engages in mentoring upcoming developers, emphasizing the importance of both technical skills and creative problem-solving in the ever-evolving world of technology. Specialties: C# Programming, Technical Writing, Software Development, AI Technologies, Educational Outreach

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top