Saving as jpeg from memorystream in c#

22,570

Solution 1

Resize the Image and Save it

Private void ResizeImage(Image img, double maxWidth, double maxHeight)
{
    double srcWidth = img.Source.Width;
    double srcHeight = img.Source.Height;

    double resizeWidth = srcWidth;
    double resizeHeight = srcHeight;

    double aspect = resizeWidth / resizeHeight;

    if (resizeWidth > maxWidth)
    {
        resizeWidth = maxWidth;
        resizeHeight = resizeWidth / aspect;
    }
    if (resizeHeight > maxHeight)
    {
        aspect = resizeWidth / resizeHeight;
        resizeHeight = maxHeight;
        resizeWidth = resizeHeight * aspect;
    }

    img.Width = resizeWidth;
    img.Height = resizeHeight;
}

You could use this code to Resize the image to the required Dimention Before saving it

Solution 2

As others have mentioned, if you want all images to be the same size without distortion, you're going to need to resize while maintaining the aspect ratio. See this function below:

public Image ResizeWithSameRatio(Image image, float width, float height)
{
    // the colour for letter boxing, can be a parameter
    var brush = new SolidBrush(Color.Black);

    // target scaling factor
    float scale = Math.Min(width / image.Width, height / image.Height);

    // target image
    var bmp = new Bitmap((int)width, (int)height);
    var graph = Graphics.FromImage(bmp);

    var scaleWidth = (int)(image.Width * scale);
    var scaleHeight = (int)(image.Height * scale);

    // fill the background and then draw the image in the 'centre'
    graph.FillRectangle(brush, new RectangleF(0, 0, width, height));
    graph.DrawImage(image, new Rectangle(((int)width - scaleWidth)/2, ((int)height - scaleHeight)/2, scaleWidth, scaleHeight));

    return bmp;
}

Now your usage function can be significantly simplified (assuming 1024x768 target images here):

public void SaveFileOnDisk(MemoryStream ms, string FileName)
{
    try
    {
        string appPath = HttpContext.Current.Request.ApplicationPath;
        string physicalPath = HttpContext.Current.Request.MapPath(appPath);
        string strpath = physicalPath + "\\Images";
        string WorkingDirectory = strpath;

        using (var original = Image.FromStream(ms))
        using (var resized = ResizeWithSameRatio(original, 1024, 768))
        {
            resized.Save(WorkingDirectory + "\\" + FileName + ".jpg");
        }
    }
    catch (Exception ex)
    {
        //lblMsg.Text = "Please try again later.";
    }
}

Note the added simplification in terms of number of variables, and disposing by using using instead of Dispose().

Share:
22,570
acadia
Author by

acadia

Updated on May 19, 2020

Comments

  • acadia
    acadia almost 4 years

    I have a method as shown below to save image as jpeg. I want to save all the pictures with the same height and width without it getting distorted.

    How can I do that? Please help

    public void SaveFileOnDisk(MemoryStream ms, string FileName)
    {
        try
        {
            string appPath = HttpContext.Current.Request.ApplicationPath;
            string physicalPath = HttpContext.Current.Request.MapPath(appPath);
            string strpath = physicalPath + "\\Images";
            string WorkingDirectory = strpath;
    
    
            System.Drawing.Image imgSave = System.Drawing.Image.FromStream(ms);
            Bitmap bmSave = new Bitmap(imgSave);
            Bitmap bmTemp = new Bitmap(bmSave);
    
            Graphics grSave = Graphics.FromImage(bmTemp);
            grSave.DrawImage(imgSave, 0, 0, imgSave.Width, imgSave.Height);
    
            bmTemp.Save(WorkingDirectory + "\\" + FileName + ".jpg");
    
    
            imgSave.Dispose();
            bmSave.Dispose();
            bmTemp.Dispose();
            grSave.Dispose();
        }
        catch (Exception ex)
        {
            //lblMsg.Text = "Please try again later.";
        }
    
    }