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

sharon glipman 441 Reputation points
2021-11-04T21:43:55.053+00:00

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.

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,828 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,249 questions
{count} votes