question

sharonglipman-9594 avatar image
0 Votes"
sharonglipman-9594 asked JackJJun-MSFT commented

What is the reason for getting a generic error occurred in GDI+ at System.Drawing.Image.Save when using different download methods?

In this question I explain better and know where is the problem.

When I'm using in both cases to download the images with this lines everything is working fine in the end it's getting to the client.DownloadFileCompleted and then at the bottom it's drawing text on images : drawOnImage.DrawText

For the satellite images I'm using now this line :

 await client.DownloadFileTaskAsync(new Uri(urls[i]), satelliteFolderImagesDownload + "\\image" + satCounter + ".gif");

but I want to convert the downloaded satellite images when they downloading to gif so I tried to use memorystream :

 using (MemoryStream ms = new MemoryStream(await client.DownloadDataTaskAsync(new Uri(urls[i]))))
                             {
                                 using (Image img = Image.FromStream(ms, true))
                                 {
                                     img.Save(satelliteFolderImagesDownload + "\\image" + satCounter + ".gif", System.Drawing.Imaging.ImageFormat.Gif);
                                 }
                             }

but when I'm using the memorystream it's getting in the end to the to the client.DownloadDataCompleted event. and in this event when it's getting to the line

 drawOnImage.DrawText(dates[i].ToString("ddd, dd MMM yyy HH':'mm"), filesRadar[i]);

It's throwing the exception.

 private async Task DownloadAsync()
         {
             using (var client = new WebClient())
             {
                 client.DownloadFileCompleted += (s, e) =>
                 {
                     if (e.Error == null)
                     {
                         urlsCounter--;
    
                         var t = urls;
    
                         if (urlsCounter == 0)
                         {
                             CheckIfImagesExist();
    
                             btnRadarPath.Enabled = true;
                             btnSatellitePath.Enabled = true;
    
                             radCounter = 0;
                             satCounter = 0;
    
                             lblStatus.Text = "Completed.";
    
                             dates = rad.dates;
                             var images = System.IO.Directory.GetFiles(radarFolderImagesDownload,
                                   "*.gif", SearchOption.AllDirectories).OrderBy(x => x).ToArray();
    
                             Array.Sort(images, new MyComparer(false));
    
                             if (images.Length > 0)
                             {
                                 for (int i = 0; i < images.Length; i++)
                                 {
                                     drawOnImage.DrawText(dates[i].ToString("ddd, dd MMM yyy HH':'mm"), images[i]);
                                 }
                             }
    
                             GetImagesFiles();
                         }
                     }
                     else
                     {
                         string error = e.Error.ToString();
                     }
                 };
    
                 client.DownloadDataCompleted += (s, e) =>
                 {
                     if (e.Error == null)
                     {
                         urlsCounter--;
    
                         var t = urls;
    
                         if (urlsCounter == 0)
                         {
                             CheckIfImagesExist();
    
                             btnRadarPath.Enabled = true;
                             btnSatellitePath.Enabled = true;
    
                             radCounter = 0;
                             satCounter = 0;
    
                             lblStatus.Text = "Completed.";
    
                             dates = rad.dates;
                                
                             Array.Sort(filesRadar, new MyComparer(false));
    
                             if (filesRadar.Length > 0)
                             {
                                 for (int i = 0; i < filesRadar.Length; i++)
                                 {
                                     drawOnImage.DrawText(dates[i].ToString("ddd, dd MMM yyy HH':'mm"), filesRadar[i]);
                                 }
                             }
                         }
                     }
                     else
                     {
                         string error = e.Error.ToString();
                     }
                 };
    
                 client.DownloadProgressChanged += (s, e) => tracker.SetProgress(e.BytesReceived, e.TotalBytesToReceive);
                 client.DownloadProgressChanged += (s, e) => lblAmount.Text = tracker.SizeSuffix(e.BytesReceived) + "/" + tracker.SizeSuffix(e.TotalBytesToReceive);
                 client.DownloadProgressChanged += (s, e) => lblSpeed.Text = tracker.GetBytesPerSecondString();
                 client.DownloadProgressChanged += (s, e) => myLong = Convert.ToInt64(client.ResponseHeaders["Content-Length"]);
                 client.DownloadProgressChanged += (s, e) =>
                 {
                     progressBar1.Value = e.ProgressPercentage;
                     label1.Text = e.ProgressPercentage + "%";
                 };
    
                 for (int i = 0; i < urls.Count; i++)
                 {
                     tracker.NewFile();
    
                     if (urls[i].Contains("Radar"))
                     {
                         await client.DownloadFileTaskAsync(new Uri(urls[i]), radarFolderImagesDownload + "\\image" + radCounter + ".gif");
    
                         radCounter++;
                     }
                     else
                     {
                         lblStatus.Text = "Downloading satellite";
    
                         await client.DownloadFileTaskAsync(new Uri(urls[i]), satelliteFolderImagesDownload + "\\image" + satCounter + ".gif");
    
                         /*using (MemoryStream ms = new MemoryStream(await client.DownloadDataTaskAsync(new Uri(urls[i]))))
                         {
                             using (Image img = Image.FromStream(ms, true))
                             {
                                 img.Save(satelliteFolderImagesDownload + "\\image" + satCounter + ".gif", System.Drawing.Imaging.ImageFormat.Gif);
                             }
                         }*/
    
                         satCounter++;
                     }
                 }
             }
         }

I can't figure out why when not using the memorystream and it's getting only to the client.DownloadFileCompleted event the DrawText is working fine but if using memorystream and it's getting to the client.DownloadDataCompleted event the DrawText throw the exception.

This is the class of the DrawOnImage :

 using System;
 using System.Collections.Generic;
 using System.Drawing;
 using System.Drawing.Text;
 using System.Globalization;
 using System.Text;
 using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
    
 namespace Extract
 {
     class DrawOnImage
     {
         public void DrawText(String text, String path)
         {
             BitmapImage bi = new BitmapImage();
             var stream = System.IO.File.OpenRead(path);
             bi.BeginInit();
             bi.CacheOption = BitmapCacheOption.OnLoad;
             bi.StreamSource = stream;
             bi.EndInit();
             stream.Close();
             stream.Dispose();
    
             string sText = text;
             int nTextHeight = 60;
             DrawingVisual drawingVisual = new DrawingVisual();
             using (DrawingContext drawingContext = drawingVisual.RenderOpen())
             {
                 drawingContext.DrawImage(bi, new Rect(0, 0, bi.Width, bi.Height));
    
                 Rect rect = new Rect(0, bi.Height, bi.Width, nTextHeight);
                 drawingContext.DrawRectangle(System.Windows.Media.Brushes.SlateGray, new System.Windows.Media.Pen(System.Windows.Media.Brushes.SlateGray, 10), rect);
    
                 FormattedText formattedText = new FormattedText(sText, CultureInfo.InvariantCulture,
     FlowDirection.LeftToRight, new Typeface("Ariel"), 20, System.Windows.Media.Brushes.White,
     VisualTreeHelper.GetDpi(drawingVisual).PixelsPerDip);
    
                 formattedText.TextAlignment = TextAlignment.Center;
                 double nX = bi.Width / 2;
                 double nY = bi.Height + nTextHeight / 2;
                 System.Windows.Point pt = new System.Windows.Point(nX, nY - formattedText.Height / 2);
                 drawingContext.DrawText(formattedText, pt);
             }
             RenderTargetBitmap bmp = new RenderTargetBitmap((int)bi.Width, (int)bi.Height + nTextHeight, 96, 96, PixelFormats.Pbgra32);
             bmp.Render(drawingVisual);
    
             GifBitmapEncoder gif = new GifBitmapEncoder();
             gif.Frames.Add(BitmapFrame.Create(bmp));
    
    
             System.IO.File.Delete(path);
    
             using (System.IO.Stream stm = System.IO.File.Create(path))
             {
                 gif.Save(stm);
             }
         }
     }
 }

On one completed event it's working but on the other completed event it's throwing the exception.


I used a breakpoint in the DrawOnImage class on all the lines and it's working fine until image number 21 out of 23 then it throw the exception but when I'm looking on the hard disk on the images all the 23 images have the text drawn. So I'm confuse about what is going on. why the exception happens only on the DownloadDataCompleted event when using the memorystream and why on image number 21 ? all the 23 images have been downloaded fine. strange.

dotnet-csharpwindows-forms
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@sharonglipman-9594, Based on my research, I find that the problem may be that the stream is not closed correctly after creating the bitmap. I suggest that you could use using statement to close the stream correctly. For example: Code.


1 Vote 1 ·

Where in the DrawOnImage class ?

I'm using Dispose there

 BitmapImage bi = new BitmapImage();
             var stream = System.IO.File.OpenRead(path);
             bi.BeginInit();
             bi.CacheOption = BitmapCacheOption.OnLoad;
             bi.StreamSource = stream;
             bi.EndInit();
             stream.Close();
             stream.Dispose();


And in form1 I tried the using already

 using (MemoryStream ms = new MemoryStream(await client.DownloadDataTaskAsync(new Uri(urls[i]))))
                         {
                             using (Image img = Image.FromStream(ms, true))
                             {
                                 img.Save(satelliteFolderImagesDownload + "\\image" + satCounter + ".gif", System.Drawing.Imaging.ImageFormat.Gif);
                             }
                         }



And the strange thing is when I download the images without the MemoryStream but with

 await client.DownloadFileTaskAsync(new Uri(urls[i]), satelliteFolderImagesDownload + "\\image" + satCounter + ".gif");


and it's not getting to the second completed event only to the first one the drawOnImage.DrawText is working fine only when I'm using MemoryStream and it's getting to the second completed event then the drawOnImage.DrawText is not working and throw the exception.

0 Votes 0 ·

In the class DrawOnImage I tried this

 BitmapImage bi = new BitmapImage();
             using (var stream = System.IO.File.OpenRead(path))
             {
                 bi.BeginInit();
                 bi.CacheOption = BitmapCacheOption.OnLoad;
                 bi.StreamSource = stream;
                 bi.EndInit();
                 stream.Close();
                 stream.Dispose();
             }

I also tried without the Close and Dispose in both tries it's working until 6-7 items maybe it's getting to the last image but then throw the exception again.

0 Votes 0 ·

@sharonglipman-9594, Could you upload your project to OneDrive or GitHub then share the link here? Currently based on your code provided, I can not reproduce your probelm.

0 Votes 0 ·

0 Answers