【问题标题】:lock image file in PictureBox在 PictureBox 中锁定图像文件
【发布时间】:2015-07-15 04:19:59
【问题描述】:

我将图像加载到图片框中:

myPictureBox.Image = Image.FromFile(strImageFile);

并且工作正常,但是图像文件被锁定,我无法管理,直到我的应用程序关闭..

我需要从程序的另一个窗口保存一个新图像以在此子窗口关闭时重新加载..

【问题讨论】:

  • 你为什么不把它保存到一个位图变量中然后用它来显示

标签: c# winforms picturebox


【解决方案1】:

作为documented从文件中加载图片,并为图片框分配一个克隆实例。

如果您想在多个 PictureBox 控件中使用相同的图像,请为每个 PictureBox 创建图像的克隆。从多个控件访问同一图像会导致发生异常。

为了保持文件解锁,只在克隆时间使用它:

using ( var img = Image.FromFile( fileName ) )
{
    pictureBox2.Image = (Image) img.Clone();
}

【讨论】:

  • 那行不通。克隆保留原始文件的链接。
  • @Nyerguds ReferenceSource 说:No, it does not
  • 实际的克隆是由GDI+系统完成的,这也是从文件中进行的原始创建。这段代码什么也没说,因为你不知道 GdipCloneImage 里面有什么。
  • @Nyerguds 说得够多了:图像类不知道位图类的流或原始文件的链接。链接怎么能在不知情的情况下被复制?
  • @Nyerguds BTW:你测试了吗?我做到了,它就像一个魅力
【解决方案2】:

一种简单的方法是将图像从文件复制到新的Bitmap,然后从文件中释放实例。最好使用适当的 using 构造来完成:

using(var fromFile = Image.FromFile(strImageFile))
{
    myPictureBox.Image = new Bitmap(fromFile);
}

【讨论】:

    【解决方案3】:

    好吧,您可以使用Image.FromStream 代替Image.FromFile 并将您正在读取的流包装到using 中,以确保在您完成阅读后它会被释放。

    using (var stream = File.Open(strImageFile, FileMode.Open))
    {
         myPictureBox.Image = Image.FromStream(stream);
    }
    

    【讨论】:

    • 我猜这行不通。您正在关闭 Image 类需要的流。想一想,当你打电话给Bitmap.SetPixel时会发生什么。
    • @SriramSakthivel 你的猜测是错误的。 ;) 实际上我已经对其进行了测试,并且它可以工作 - 所以看起来你在完成 Image.FromStream 后不需要保持流打开
    • Image.FromStream documentation says 您必须在图像的生命周期内保持流打开。
    • @SriramSakthivel 正如我所说 - 我测试了这种方法,并且它有效 - 图像在图片框中正确显示并且源文件未锁定。不仅如此 - 如果您查看 Image 类源(EnsureSave 方法实际上从流中读取图像) - 您会发现在 EnsureSave 完成后不需要打开流)。所以我不知道为什么MSDN坚持要在Image.FromStream完成后打开stream。
    • 它只是有效的事实并不意味着它将继续有效。如果文档没有提到它,我们可以假设它会起作用,但是当文档明确说您必须保持流打开时,您应该保持它打开。我害怕使用违反文档的东西,因为他们可以随时更改实现。
    【解决方案4】:

    Image.FromFile 将保持文件打开,这会阻止对图像文件的访问,直到图像被处置。如果要释放锁,则需要将Image文件保存在内存中。

    myPictureBox.Image = Image.FromStream(new MemoryStream(File.ReadAllBytes(strImageFile)));
    

    【讨论】:

    • FileStream 读取图像而不是将文件内容复制到MemoryStream 首先看起来更优雅一些。
    • @AndyKorneyev 优雅,是的。但是您需要在Image 的整个生命周期内保持FileStream 处于打开状态。这与调用Image.FromFile 相同。它不会帮助 OP。
    猜你喜欢
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多