Hi I am trying to upload some images async, I get Out of Memory Exception, I am disposing by using statement however I get following stack trace
[OutOfMemoryException: Out of memory.]
System.Drawing.Graphics.CheckErrorStatus(Int32 status) +1146420
System.Drawing.Graphics.DrawImage(Image image, Rectangle destRect, Int32 srcX, Int32 srcY, Int32 srcWidth, Int32 srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttrs, DrawImageAbort callback, IntPtr callbackData) +256
System.Drawing.Graphics.DrawImage(Image image, Rectangle destRect, Int32 srcX, Int32 srcY, Int32 srcWidth, Int32 srcHeight, GraphicsUnit srcUnit, ImageAttributes imageAttr) +48
Here is resizer, where I get exception:
public Bitmap ResizeImage(Image image, int width, int height)
{
var newWidth = (int)(imageWidth * ratio) < 210 ? 210 : (int)(imageWidth * ratio);
var newHeight = (int)(imageHeight * ratio) < 210 ? 210 : (int)(imageHeight * ratio);
//Image resize logic
var destRect = new Rectangle(0, 0, newWidth, newHeight);
var destImage = new Bitmap(newWidth, newHeight);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
/*Here I get error*/graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel,
wrapMode);
}
}
return destImage;
}
Here which uploads image:
private async Task<short> UploadImage(string title, HttpPostedFileBase file, short dimensionWidth,
short dimensionHeight)
{
var blockBlob = CloudBlobContainer.GetBlockBlobReference(title);
var jpgInfo = ImageCodecInfo.GetImageEncoders().First(codecInfo => codecInfo.MimeType == "image/jpeg");
using (var image = Image.FromStream(file.InputStream, true, true))
{
using (var stream = new MemoryStream())
using (var encParams = new EncoderParameters(1))
{
encParams.Param[0] = new EncoderParameter(Encoder.Quality, 60L);
if (image.Width > dimensionWidth && image.Height > dimensionHeight)
using (Bitmap bitMapImage = ResizeImage(image, dimensionWidth, dimensionHeight))
{
bitMapImage.Save(stream, jpgInfo, encParams);
}
else
{
image.Save(stream, jpgInfo, encParams);
}
stream.Position = 0;
await blockBlob.UploadFromStreamAsync(stream);
blockBlob.Properties.CacheControl = "public, max-age=864000";
blockBlob.SetProperties();
}
}
return (short)EnumData.EOpStatus.Success;
}
Here is main function:
public async Task<string> UploadImages(string title, IEnumerable<HttpPostedFileBase> files, short fileCount)
{
var fileIndex = 0;
var imageCsv = String.Empty;
var uploadTask = new Task<short>[fileCount * 2];
foreach (var file in files)
{
var fullTitle = title + "-" + Convert.ToString(fileIndex) + Path.GetExtension(file.FileName);
uploadTask[fileIndex] = UploadImage(fullTitle, file, 1440, 900);
uploadTask[fileIndex + 1] = UploadImage("thumb-" + fullTitle, file, 280, 280);
imageCsv += String.IsNullOrEmpty(imageCsv) ? fullTitle : "," + fullTitle;
/*await Task.WhenAll(uploadTask[fileIndex], uploadTask[fileIndex + 1]);*///Works fine in this case
fileIndex += 2;
}
await Task.WhenAll(uploadTask);
return imageCsv;
}
So after some uploads I get an error
Performance Monitor seems normal through out application use, I think its normal
I believe you are indeed trying to paint outside the destination rectangle... if you notice your code you are in fact (in the line marked) painting image.Width
and image.Height
(original dimensions), and not the ratio-applied dimensions...
Dispose sourceImage and destImage after job is done.
来源:https://stackoverflow.com/questions/33865130/out-of-memory-exception-while-uploading-and-resizing-multiple-images-asynchronou