返回由Image.FromStream(Stream stream)方法创建的图像

时间:2014-08-07 16:03:17

标签: c# image stream dispose

我有这个函数在函数中返回一个Image,使用 Image.FromStream 方法创建图像 根据{{​​3}}:

  

您必须在图片的生命周期内保持流打开

所以我没有关闭流(如果我关闭了蒸汽,则从返回的图像对象中抛出GDI +异常)。我的问题是,当在返回的图像上的其他位置调用 Image.Dispose()时,流是否将关闭/处置

public static Image GetImage(byte[] buffer, int offset, int count)
{
    var memoryStream = new MemoryStream(buffer, offset, count);
    return Image.FromStream(memoryStream);
}

正如其中一个答案中所建议的,使用不是要走的路,因为它会引发异常:

public static Image GetImage(byte[] buffer, int offset, int count)
{
    using(var memoryStream = new MemoryStream(buffer, offset, count))
    {
         return Image.FromStream(memoryStream);
    }
}

public static void Main()
{
   var image = GetImage(args);
   image.Save(path); <-- Throws exception
}
  1. 根据一些人明确处理/关闭 MemoryStream 是没有必要的,因为它不使用任何非托管资源,其他人说相反的事情,所以它的那种困境。
  2. Image.Dispose 方法不会处理创建图像的流ftom
  3. Image类没有对传递给 Image.FromStream 方法的Stream的任何引用,因此最终将由 GC ...收集流?因此 Image.Save 方法
  4. 中的例外情况
  5. 返回一个包装类,其中包含对流的引用和由它创建的Image,因此我们可以 dispose 这两个...?或者只是使用标记属性来保留对父流的引用......?
  6. 使用 MemoryStream 时,似乎只会出现此问题。如果图像是从 ConnectStream 创建的,即使父流已被处理,也不会发生错误

3 个答案:

答案 0 :(得分:4)

尽管有其他建议要做,但在图像处理之前,不应关闭或处理流。

MSDN州:

  

您必须在图像的生命周期内保持流打开。

对于某些流,例如MemoryStream,处理没有多大用处,因为它没有分配非托管资源。另一方面,文件流也是如此,因此,除非您非常确定流是安全的,否则在完成图像后应始终处理流。

答案 1 :(得分:2)

由于您只构建一个Image然后保存它,请考虑使用此实现:

  public static void GetAndSaveImage(byte[] buffer, int offset, int count,string path)
  {
      using(var memoryStream = new MemoryStream(buffer, offset, count))
      using(var img = Image.FromStream(memoryStream))
      {
          img.Save(path);
      }
  }

答案 2 :(得分:1)

处理图像不会影响内存流,如下例所示:

static void Main(string[] args) {

        byte[] contents = File.ReadAllBytes(DESKTOP_PATH + "asample.tif");
        MemoryStream ms = new MemoryStream(contents);
        Image img = Image.FromStream(ms);
        img.Dispose();
        Image img2 = Image.FromStream(ms);
        Console.WriteLine(img2.PixelFormat);
        Console.ReadKey();


    }

这将输出“Format32bppPargb”。我建议把它包装成一个像这样的使用语句:

using (MemoryStream ms = new MemoryStream(contents){
            // code here
        }