I am totally stuck on image resizing because I am getting OutOfMemoryException using the typical examples of image resizing that can be found on the many questions that feature OOMs.
I even tried DynamicImage, which can be found on Nuget, and this also threw an OutOfMemoryException.
Can anyone tell me how I can reduce the quality/size of an image in C#, without loading it into memory?
Edit: I want the c# equivalent to this, if there is one?
Edit: I give up with the typical methods of resizing, as I just can’t avoid OutOfMemoryExceptions on my live site, which is running on an old server.
Further Edit: My server’s OS is Microsoft Server 2003 Standard Edition
I can post examples of my code, but I’m trying to find a way around OutOfMemoryExceptions.
public static void ResizeImage(string imagePath, int imageWidth, int imageHeight, bool upscaleImage) {
using (Image image = Image.FromFile(imagePath, false)) {
int width = image.Width;
int height = image.Height;
if (width > imageWidth || height > imageHeight || upscaleImage) {
image.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX);
image.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX);
float ratio = 0;
if (width > height) {
ratio = (float)width / (float)height;
width = imageWidth;
height = Convert.ToInt32(Math.Round((float)width / ratio));
}
else {
ratio = (float)height / (float)width;
height = imageHeight;
width = Convert.ToInt32(Math.Round((float)height / ratio));
}
using (Bitmap bitmap = new Bitmap(width, height)) {
bitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (Graphics graphic = Graphics.FromImage(bitmap)) {
graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphic.DrawImage(image, 0, 0, width, height);
string extension = ".jpg"; // Path.GetExtension(originalFilePath);
using (EncoderParameters encoderParameters = new EncoderParameters(1)) {
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
using (MemoryStream imageMemoryStream = new MemoryStream()) {
bitmap.Save(imageMemoryStream, GetImageCodec(extension), encoderParameters);
using (Image result = Image.FromStream(imageMemoryStream, true, false)) {
string newFullPathName = //path;
result.Save(newFullPathName);
}
}
}
}
}
}
}
}
I also tried this code as I hoped GetThumbnailImage would reduce the picture quality/size for me, but this is also throwing an OOM exception:
viewModel.File.SaveAs(path);
Image image = Image.FromFile(path);
Image thumbnail = image.GetThumbnailImage(600, 600, null, new IntPtr());
image.Dispose();
File.Delete(path);
thumbnail.Save(path);
thumbnail.Dispose();
Again, both my code examples work for me in my local machine, so I am not trying to find faults/fixes in the code as they should be fine. I’m looking for any solution to avoid the OOM exceptions, I had the idea of reducing the fize size somehow without loading the image into memory, but any alternative ideas that can help me would be appreciated.
I failed to mention that I inherited legacy code that was not disposing of images properly, because I did not think it was relevant since fixing it. The strange thing is, after restarting the website and the AppPool, I was able to upload pictures again without getting an OutOfMemoryExcepiton. I’m struggling to understand why this happened as I have changed the code to dispose of images properly and have done several deploys since, so I would expect that to clear any undisposed images from memory? All the code for picture resizing and uploading was in a static class and I believe that GC.collect() does not work on static variables?
My theory is that the undisposed images have built up in memory and have remained even when I have redepolyed to the site, as that’s the only conclusion I can reach since the code began working again after restarting the app pool.
I would delete my question but it has been answered now, happy to reassign the answer if anyone can help explain what was going on here.