0

I am using C#,MVC5 and I am uploading image from my web application but I realize that I have performance issues because I don't optimize them and I need to fix it and is important to keep the quality. Below you can see the results of the report why is slow.

enter image description here

How can I do it?

I am saving the files into a path locally with the below code.

string imgpathvalue = ConfigurationManager.AppSettings["RestaurantPath"];
 
string path = System.IO.Path.Combine(Server.MapPath(imgpathvalue));

if (!Directory.Exists(path))
 {
     Directory.CreateDirectory(path);
 }
 string pic = System.IO.Path.GetFileName(restaurantImg.FileName.Replace(" ", "_").Replace("%", "_"));
              path = System.IO.Path.Combine(Server.MapPath(imgpathvalue), pic);
                    // file is uploaded

 restaurantImg.SaveAs(path);

I have try the code below but I am getting the error "A generic error occurred in GDI+."

  System.Drawing.Bitmap bmpPostedImage = new System.Drawing.Bitmap(restaurantImg.InputStream);
                    System.Drawing.Image objImage = ResizeImages.ScaleImage(bmpPostedImage, 81);
                    using (var ms = new MemoryStream())
                    {
                        objImage.Save(ms, objImage.RawFormat);
                        //ResizeImages.getImage(ms.ToArray());

                    }
 public static System.Drawing.Image ScaleImage(System.Drawing.Image image, int maxHeight)
        {
            var ratio = (double)maxHeight / image.Height;
            var newWidth = (int)(image.Width * ratio);
            var newHeight = (int)(image.Height * ratio);
            var newImage = new Bitmap(newWidth, newHeight);
            using (var g = Graphics.FromImage(newImage))
            {
                g.DrawImage(image, 0, 0, newWidth, newHeight);
            }
            return newImage;
        }
marios
  • 261
  • 8
  • 26
  • You shouldn't use `System.Drawing` from within ASP.NET. Use a library like ImageMagick instead. – Dai Sep 23 '20 at 06:24
  • ImageMagick resize and optimize the images? Can you share some code based on my code? – marios Sep 23 '20 at 06:26
  • https://stackoverflow.com/questions/10337800/resize-with-crop-using-imagemagick-net-and-c-sharp – Dai Sep 23 '20 at 06:33
  • what width and height is the best to keep the same quality and not to be starched ? – marios Sep 23 '20 at 06:36

1 Answers1

0

You are missing some of the code to resize your image correctly. Appending is a function that correctly resizes images depending on the Width and Height Values you give to it (in this example the image gets resized to 120*120 if possible).

Function Call:

ResizeImage("Path to the Image you want to resize", 
    "Path you want to save resizes copy into", 120, 120);

To make a function call like that possible we need to write our function. Which takes the image from the sourceImagePath and creates a new Bitmap.

Then it calculates the factor to resize the image and depending on if either the width or height is bigger it gets adjusted accordingly.

After that is done we create a new BitMap fromt he sourceImagePath and resize it. At the end we also need to dispose the sourceImage, the destImage and we also need to dispose of the Graphics Element g that we used for different Quality Settings.

Resize Function:

private void ResizeImage(string sourceImagePath, string destImagePath, 
    int wishImageWidth, int wishImageHeight)
{
    Bitmap sourceImage = new Bitmap(sourceImagePath);
    Bitmap destImage = null;
    Graphics g = null;
    int destImageWidth = 0;
    int destImageHeight = 0;

    // Calculate factor of image
    double faktor = (double) sourceImage.Width / (double) sourceImage.Height;

    if (faktor >= 1.0) // Landscape
    {
        destImageWidth = wishImageWidth;
        destImageHeight = (int) (destImageWidth / faktor);
    }
    else // Port
    {
        destImageHeight = wishImageHeight;
        destImageWidth = (int) (destImageHeight * faktor);
    }

    try
    {
        destImage = new Bitmap(sourceImage, destImageWidth, destImageHeight);
        g = Graphics.FromImage(destImage);
        g.InterpolationMode = 
            System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
        g.SmoothingMode = 
            System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
        g.PixelOffsetMode = 
            System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; 
        g.CompositingQuality = 
            System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        g.DrawImage(sourceImage, 0, 0, destImageWidth, destImageHeight);
        // Making sure that the file doesn't already exists.
        if (File.Exists(destImagePath)) {
            // If it does delete the old version.
            File.Delete(destImagePath);
        }
        destImage.Save(destImagePath);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine("*** ERROR-Terror: " + ex.Message)
    }
    finally
    {
        if (g != null) { g.Dispose(); g = null; }
        if (destImage != null) { destImage.Dispose(); destImage = null; }
    }

    sourceImage.Dispose();
    sourceImage = null;
}

IndieGameDev
  • 2,905
  • 3
  • 16
  • 29
  • This code does not guarantee that the `Bitmap` and `Graphics` objects will be disposed along all code-paths. You should be using `using()` blocks and there is no need to `catch` here, and using `Console.WriteLine` is a NOOP in ASP.NET. – Dai Sep 23 '20 at 06:55
  • I am getting an error A generic error occurred in GDI+ in the catch section because is already there with the same name on the same path. Can i replace it or should i delete it first? – marios Sep 23 '20 at 07:10
  • You can delete the image before creating the new one with File.Delete if it exists File.Exists – IndieGameDev Sep 23 '20 at 07:16
  • @marios I've added code to ensure that you can save the file even if there is already a file with that name in the same directory. – IndieGameDev Sep 23 '20 at 07:21