0

I am using the System.Drawing.Common 5.0.1 nuget package in a ASP Net Core (5) application and want to convert an image (can be jpeg, png etc.) to png (if not already png).

When the image has been uploaded successfully I try to convert it with following code (the image bytes are available in uploadResult.FileData):

byte[] imageBytes;
            if (fileExtension.ToLower() != "png")
            {
                using (var ms = new MemoryStream(uploadResult.FileData))
                {
                    using(Image image = Image.FromStream(ms))
                    {
                        image.Save(ms, ImageFormat.Png);
                        imageBytes = ms.ToArray();
                    }
                }
            }

It always fails on this line: image.Save(ms, ImageFormat.Png);

Exception: An exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.Common.dll but was not handled in user code: 'A generic error occurred in GDI+.'

I know that there are many posts regarding this error message on this site and they contain good answers but I believe I followed them. Also most questions use an image from the filesystem or write to it but my image is already available as byte array and I write to a memorystream - but I cannot see what's possibly causing this.

Patric
  • 2,789
  • 9
  • 33
  • 60
  • 5
    Wait... you're trying to read from a memory stream and write to the end of the same memory stream? – ProgrammingLlama Feb 16 '21 at 09:17
  • 1
    uahh, I think I see your point. I most likely need another memory stream as target to get the bytes of the converted image... I have to try this out. – Patric Feb 16 '21 at 09:24
  • Note that gdi+ is _explicitly_ not supported on ASP, due to too many parallel users on the webapp inevitably overflowing the hardcoded object limits in gdi+. – Nyerguds Jul 20 '21 at 09:51

1 Answers1

1

OK, got it working, thanks to the comment of John with the following approach:

                using (var ms = new MemoryStream(uploadResult.FileData))
                {
                    using (var targetMs = new MemoryStream())
                    {
                        using(Image image = Image.FromStream(ms))
                        {
                            image.Save(targetMs, ImageFormat.Png);
                            imageBytes = targetMs.ToArray();
                        }
                    }
                }

Not sure if this is the best, or at least a good approach. If someone comes up with something better (especially regarding performance/memory usage) I would like to see it.

Patric
  • 2,789
  • 9
  • 33
  • 60