Search code examples
c#imagejpeg

C# Image.Save() cause Cannot access a closed Stream when saving JPG file (PNG works)


I've got strange behavior.

I have a code, when I am sending byte[] array to the Image (sometimes png, sometimes jpg).

When I save PNG format - everything is ok, but when I am trying to save JPG, there is an exception: "Cannot access a closed Stream"

Code:

imgTarget.Save(wwwroot + "\\ImageBank\\" + TaskRunID + "_" + TestCaseID + "_" + TestDataID + "_" + ImageCounter + Extension, ImageFormat.Jpeg);

What I have checked:

  • imgTarget is not null
  • imgTarget contains correct data (even RawFormat is Png or Jpeg as It should)
  • imgTarget.Save() throws an exception: System.ObjectDisposedException: 'Cannot access a closed Stream.'
  • I have tried to use Bitmap - copy imgTarget to new Bitmap and then Save (with the same result)
  • I have tried to call Save() method with the ImageFormat parameter correctly set to jpeg or png (with the same result) - for both for Image.Save() and Bitmap.Save()
  • I have checked the correct path and file name (it's ok) (in this case it is C:\MyProd\wwwroot\ImageBank\10611_8_-1_1.jpeg)

Strange is that imgTarget contains data just before calling the method Save() - but right after it is null/disposed...

Anyone any ideas?

EDIT:

I have prepared little bit of code which is failing in the same way - it fails at last line .Save()

// This contains only the URL for the downloading of the file
string url = $"***url to download jpg file***";

// Request for the API - which downloads the jpg file via GET and provide the RawData via Response.RawBytes
APIRequest request = new APIRequest(RestSharp.Method.GET, url, new Authentication("user", "password", "-1"));

// Test case is only class which calls RestSharp (get png or jpg file)
TestCase t = new TestCase();
// This downloads the jpg file and store it as byte[] in t.GetDataFromAPI
t.API(request);
// Using downloaded data as byte[]
byte[] APIImageSource = t.GetDataFromAPI;
// Default extensions for saving files is .png
string Extension = ".png";
            

Image imgTarget;
// Now I use bytes[] and convert them into the image
imgTarget = ConvertBytesToImage(APIImageSource);
if (t.GetImageFormat(APIImageSource) == ExpectedFormat.JPEG)
{
     Extension = ".jpeg";
}
string path = "C:\\Temp\\filename" + Extension;
imgTarget.Save(path + Extension, ImageFormat.Jpeg);

There is Method ConvertBytesToImage:

internal static Image ConvertBytesToImage(byte[] bytes)
{
    using (var ms = new MemoryStream(bytes))
    {
        return Image.FromStream(ms);
    }
}

Solution

  • Comment from @Simon Mourier is the solution:

    remove the using on the MemoryStream, or remove that ConvertBytesToImage and keep the MemoryStream alive until you completely saved the image. – Simon Mourier 1 min ago

    I don't understand why, but I have removed the using statement and now it works.

    Thank all of You