2012-02-03 115 views
2

现在我有一个应用程序,将一堆缩略图加载到PictureBox控件中。有时超过一百次。这些图像是使用Image.FromStream(MemoryStream)创建的,而内存流代表每个JPG文件。图像加载和流/文件依赖

目前,只要我调用Image.FromStream,我将引用分配给图片框,然后在I Flush()和Dispose()之后立即分配流。

根据文档,我不应该释放流,直到我完成了图像。但是,我没有这样做过任何错误。我的PictureBox控件甚至可以在内存流很长时间处理后,使用缩略图图像整天重新绘制自己。

但是,如果我尝试以任何方式访问这些图像,例如调用Save函数,则会引发错误。

  • 如果一个位图对内存流或文件流的依赖,这将部署在处置它的来源?或者仅当它使用Bitmap.FromFile创建流本身时?

  • 正在处理MemoryStream,就像我正在考虑的那样好吗? PictureBox必须以某种方式缓存图像。我从来没有发生错误,因为一旦设置好了,我就不需要触摸图像。

我还注意到,它需要我的PictureBoxes很长时间来绘制他们的父控制。我不确定这是因为我有太多的控件,或者是第一次在PictureBox中绘制图像时出现延迟。

我知道当你用一个文件参数创建一个新的位图时,它实际上并没有加载文件内容,直到第一次需要。我的问题是,我不希望每个OnPaint操作都被文件读取延迟,我想确保在我尝试绘制控件之前预加载数据,否则会出现闪烁和缓慢的绘制。

是否有强制图像被预加载的好方法? Image.FromFile,Image.FromStream,新的Bitmap(fileName)等之间有什么不一致?是否所有这些都会立即加载所有字节,还是延迟到第一次需要时为止?

这里是我的代码:

MemoryStream ms = new MemoryStream(bytes); // byte[] array 
pictureBox.Image = Image.FromStream(ms); 
ms.Flush(); 
ms.Dispose(); 

回答

1

GDI +其中伏于图像类别要求的源数据流保持开放,而图像中存在的正常工作。在Image使用它时将更改写入源流也是一个好主意。更改应保存到不同的流中。

从Image派生的所有东西都使用了封面下的Stream。他们的加载行为是相同的。

图像不关闭或处置,将其通过FromStream提供给它的流。你必须自己管理。

此外,要求一个流冲洗只有当流已经写入的效果。

如果你正在寻找改善你的PictureBoxes UI行为,试试这个:

  1. 设置InitialImage一个小微调GIF。
  2. 将WaitOnLoad设置为false。
  3. 通过设置ImageLocation指定图像。 (您可以使用文件规格或其中的URL。)
  4. 使用LoadAsync方法异步加载图像。
0

1)

如果一个位图对内存流或文件流的依赖,将 进行处置,当你处理它的来源?或者这只有当它 它使用Bitmap.FromFile创建流本身?

在​​看看:

你必须保持流打开图像的寿命。

2)

在PictureBox必须缓存以某种方式图像。我从未有过 的错误,因为一旦设置完成后我不需要触摸图像。

你刚才应该不是因为(在使用它,即图片框),它已被分配给图片框处置Image实例和,而图片框使用它。否则,PictureBox将尝试使用已处理的图像,并且会导致一些“不好”的后果。

PictureBox.Image Property

注意:如果你想使用相同的图像多的PictureBox控件 ,为每个图片框图像的克隆。访问 来自多个控件的相同图像会导致发生异常。

更新:

样品具有几乎相同的场景:HOW TO: Copy a Picture from a Database Directly to a PictureBox Control with Visual C#

+0

你从我的测试看我的结果吗?我处理了用于Image.FromStream的流,但我的PictureBox控件仍然很好地绘制。我只是想弄清楚为什么会发生这种情况,以便更好地理解如何从PictureBoxes获得最佳性能。 – 2012-02-03 19:20:26

+0

@Moozhe,我想,MemoryStream Dispose()实际上并没有**配置内存,因为MemoryStream实现:它使用简单的字节数组(它将被垃圾收集)。你可以试试FileStream类的实验吗? – 2012-02-03 19:25:17

+0

这听起来是正确的,因为MemoryStream没有分配内存...... PictureBox必须持有对byte []数组内存地址的引用,这就是为什么它没有被垃圾收集。 – 2012-02-03 19:36:39

相关问题