Out of Memory exception while uploading and resizing multiple images asynchronously

你。 提交于 2019-12-01 21:48:23

问题


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


回答1:


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...




回答2:


Dispose sourceImage and destImage after job is done.



来源:https://stackoverflow.com/questions/33865130/out-of-memory-exception-while-uploading-and-resizing-multiple-images-asynchronou

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!