Resizing a JPEG image in C# reduces its resolution

14,500

Solution 1

In short, DPI is not important in this case

Nicely explained on this answer.

DPI stands for Dots Per Inch. One clue as to the 96dpi reset comes from wikipedia:

... many Windows software programs have been written since the 1980s to assume that the screen provides 96 PPI

In reality, your screen will display your image at it's resolution, the DPI (or PPI, Pixels Per Inch) is determined by your screen size. DPI really only comes into play when printing your image.

Depending on which device you are printing on the DPI will vary.

Solution 2

private static Bitmap _resize(Image image, int width, int height)
{
    Bitmap newImage = new Bitmap(width, height);
    //this is what allows the quality to stay the same when reducing image dimensions
    newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
    using (Graphics gr = Graphics.FromImage(newImage))
    {
        gr.SmoothingMode = SmoothingMode.HighQuality;
        gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
        gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
        gr.DrawImage(image, new Rectangle(0, 0, width, height));
    }
    return newImage;
}

Solution 3

JPEG actual resolution is certain width by height pixels - this is what really matters. So the real important step is ImageUtilities.ResizeImage to newer resolution.

DPI resolution field is informational only and provides a sort of a hint for how large the original pixel was in first place. So, after resizing pixels you are to update DPI field to whatever value you think it should be.

Share:
14,500
shabby
Author by

shabby

have discovered that knowldge is to know what you know and where to look for what you don't But now everyone is knowledgeable, for they look for SO

Updated on June 05, 2022

Comments

  • shabby
    shabby almost 2 years

    What i have:

       A JPEG image with 96dpi, size: 540 X 700
    

    What i Want: JPEG image with 300dpi, size: 771 X 1000

    Problem: When i resize the image first and then try to change the resolution, through the following code it doesnt work

           /// <summary>
        /// Changes the resolution of the image
        /// </summary>
        /// <param name="imgPath">Image Path</param>
        /// <param name="xResolution">x Resolution</param>
        /// <param name="yResolution">y Resolution</param>
        /// <returns>Modified Image Path</returns>
        private string ChangeResolution(string imgPath, int xResolution, int yResolution)
        {
            string fullFileName = Path.GetFileNameWithoutExtension(imgPath);
            string extension = Path.GetExtension(imgPath);
            string tmpFileSavedPath = outputDir + "\\" + fullFileName + "_." + extension + "_tmp";
    
            Image original = Bitmap.FromFile(imgPath);
            original.Save(tmpFileSavedPath);
    
            Bitmap bmSmall = new Bitmap(tmpFileSavedPath);
            bmSmall.SetResolution(xResolution, yResolution);
            string modifiedOverLayImagePath = tmpFileSavedPath.TrimEnd("_tmp".ToCharArray());
            bmSmall.Save(modifiedOverLayImagePath);
            bmSmall.Dispose();
    
            //Deleting temp file
            System.IO.File.Delete(tmpFileSavedPath);
            return modifiedOverLayImagePath;
        }
    

    means it does nothing to the image, the resolution remains the same, if i go other way round, i.e. change resolution first and then change the size, surprisingly the size gets changed but the resolution is reduced back to 96dpi.

    Here is the resizing code:

    public static System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, int width, int height)
        {
            //a holder for the result
            Bitmap result = new Bitmap(width, height);
    
            //use a graphics object to draw the resized image into the bitmap
            using (Graphics graphics = Graphics.FromImage(result))
            {
                //set the resize quality modes to high quality
                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //draw the image into the target bitmap
                graphics.DrawImage(image, 0, 0, result.Width, result.Height);
            }
    
            //return the resulting bitmap
            return result;
        }
    

    Can anybody help me out, i am wondering if 771 X 1000 supports 300dpi resolution, but when i do this in photoshop it works perfectly, thanks

    Following is my main function in which i am changing resolution first and resizing afterwards:

    string imgPath = @"D:\abc\background.jpg";
    
            string newResPath = ChangeResolution(imgPath, 300, 300);
    
            Image oldImage = Bitmap.FromFile(newResPath);
            //Image newImage = ImageResize.ConstrainProportions(oldImage, 771, ImageResize.Dimensions.Width);
            Image newImage = ImageUtilities.ResizeImage(oldImage, 771, 1000);
            string savedPath = "D:\\abc\\saved.jpg";
    
            try
            {
                newImage.Save(savedPath, ImageFormat.Jpeg);
            }
            catch
            {
                MessageBox.Show("error");
            }
            newImage.Dispose();