?
Solved

Determine size of image in memory

Posted on 2011-10-10
6
Medium Priority
?
432 Views
Last Modified: 2012-05-12
I have a .Net 4 Windows Forms project created with Visual Studio 2010 using c#.

I need to open an image file (jpg or gif) and resize the dimensions to a fixed size and then adjust the quality of the image until the image size is 30kb or less. Is there a way to calculate the memory used by this image while in memory?  I don't want the overhead of saving it to disk to check System.IO.FileInfo.  I would be happy to use a free library or utility which would help.

Scott
0
Comment
Question by:canuckconsulting
  • 4
  • 2
6 Comments
 
LVL 17

Expert Comment

by:Carlos Villegas
ID: 36945772
Hello, I know how to do that for jpg files, but for gif files... I think that is more complex because to control the quality (therefore the file size) you need to play with the color palette... the next code can help you to control the size of your jpg files:
private void TestExample()
{
    ResizeImage(@"C:\Temp\MyOriginalImage.jpg", @"C:\Temp\MyResizedImage.jpg", 640, 30000);
}

private void ResizeImage(string imageFilePath, string imageFilePathOutput, int newWidth, int maxImageFileSize)
{
    using (Image myImage = Image.FromFile(imageFilePath))
    {
        Size newSize = myImage.Size;
        if (newSize.Width > newWidth)
            newSize = Resize(newSize, newWidth);

        using (Image myResizedImage = new Bitmap(myImage, newSize))
        {
            EncoderParameters eps = null;
            ImageCodecInfo ici = null;
            string fileExt = System.IO.Path.GetExtension(imageFilePath).ToLower();
            switch (fileExt)
            {
                case ".jpg":
                    eps = new System.Drawing.Imaging.EncoderParameters(1);
                    ici = GetEncoderInfo(ImageFormat.Jpeg);
                    break;
                default:
                    throw new NotImplementedException("Image format not supported");
            }

            // Starting quality
            long qualityValue = 90;
            long lastSize = 0;
            while (true)
            {
                eps.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityValue);

                using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                {
                    myResizedImage.Save(ms, ici, eps);

                    if (ms.Length <= maxImageFileSize || (lastSize > 0 && lastSize <= ms.Length))
                    {
                        // Write new image file.
                        System.IO.File.WriteAllBytes(imageFilePathOutput, ms.ToArray());
                        return;
                    }
                    lastSize = ms.Length;
                }

                // Decrease quality
                qualityValue -= 5;
            }
        }
    }
}

private static Size Resize(Size size, int newWidth)
{
    float factor = (float)size.Height / size.Width;
    return new Size(newWidth, Convert.ToInt32(newWidth * factor));
}

private static ImageCodecInfo GetEncoderInfo(ImageFormat format)
{
    return ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == format.Guid);
}

Open in new window

0
 
LVL 17

Expert Comment

by:Carlos Villegas
ID: 36946478
I forgot to mention that you will require these namespaces:
 System.Drawing
 System.Drawing.Imaging
0
 

Author Comment

by:canuckconsulting
ID: 36978782
This is perfect; thanks!  Can you advis if it is possible to convert the contents of ms back into an Image?  I would like the method to return the reduced image which will be saved later on?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 17

Accepted Solution

by:
Carlos Villegas earned 2000 total points
ID: 36979159
Hello, this is what you need?
public Image ResizeImage(string imageFilePath, int newWidth, int maxImageFileSize)
{
    using (Image myImage = Image.FromFile(imageFilePath))
    {
        Size newSize = myImage.Size;
        if (newSize.Width > newWidth)
            newSize = Resize(newSize, newWidth);

        using (Image myResizedImage = new Bitmap(myImage, newSize))
        {
            EncoderParameters eps = null;
            ImageCodecInfo ici = null;
            string fileExt = System.IO.Path.GetExtension(imageFilePath).ToLower();
            switch (fileExt)
            {
                case ".jpg":
                    eps = new System.Drawing.Imaging.EncoderParameters(1);
                    ici = GetEncoderInfo(ImageFormat.Jpeg);
                    break;
                default:
                    throw new NotImplementedException("Image format not supported");
            }

            // Starting quality
            long qualityValue = 90;
            long lastSize = 0;
            while (true)
            {
                eps.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityValue);

                using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
                {
                    myResizedImage.Save(ms, ici, eps);

                    if (ms.Length <= maxImageFileSize || (lastSize > 0 && lastSize <= ms.Length))
                    {
                        // Return the new image file.
                        return Image.FromStream(new System.IO.MemoryStream(ms.ToArray()));
                    }
                    lastSize = ms.Length;
                }

                // Decrease quality
                qualityValue -= 5;
            }
        }
    }
}

Open in new window

0
 

Author Closing Comment

by:canuckconsulting
ID: 36982860
Perfect...thank you!
0
 
LVL 17

Expert Comment

by:Carlos Villegas
ID: 36988699
Glad to help!
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Adults who share images on social media aren’t the only ones who need to worry about their privacy. Our culture’s tendency to share every move and celebration affects the privacy of our children, too.
The goal of the tutorial is to teach the user what exposure is and how to use the exposure slider. Analyze the photo that you want to edit, then adjust the exposure slider to your liking.
The goal of the tutorial is to teach the user how to use import presets downloaded from the internet into Adobe Lightroom. Once you downloaded the presets go into the preset folder and press import then import your preset and your set it to go.
Suggested Courses
Course of the Month13 days, 20 hours left to enroll

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question