C# 在PictureBox中锁定图像文件

C# 在PictureBox中锁定图像文件,c#,winforms,picturebox,C#,Winforms,Picturebox,我将图像加载到picturebox中: myPictureBox.Image = Image.FromFile(strImageFile); 并且工作正常,但图像文件已锁定,在关闭应用程序之前我无法管理 我需要从程序的另一个窗口保存一个新图像,以便在关闭此子窗口时重新加载。图像。FromFile将保持文件打开,从而在图像被释放之前阻止对图像文件的访问。如果要释放锁,需要将图像文件保留在内存中 myPictureBox.Image = Image.FromStream(new MemoryStr

我将图像加载到picturebox中:

myPictureBox.Image = Image.FromFile(strImageFile);
并且工作正常,但图像文件已锁定,在关闭应用程序之前我无法管理


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

图像。FromFile
将保持文件打开,从而在图像被释放之前阻止对图像文件的访问。如果要释放锁,需要将图像文件保留在内存中

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

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

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

一种简单的方法是将图像从文件复制到新的
位图
,然后从文件中处理实例。最好使用适当的using构造:

using(var fromFile = Image.FromFile(strImageFile))
{
    myPictureBox.Image = new Bitmap(fromFile);
}
从文件加载图像并将克隆实例指定给图片框

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

要使文件处于解锁状态,只需在克隆时使用它:

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

为什么不把它保存到一个位图变量中,然后用它来显示,我想这是行不通的。您正在关闭Image类需要的流。想想看,当你调用
Bitmap.SetPixel
@SriramSakthivel时会发生什么,你的猜测是错误的事实上,我已经测试过它了,它很有效-所以看起来在你完成
Image之后你不需要保持流打开。FromStream
Image。FromStream
你必须在图像的生命周期内保持流打开。@srramsakthivel正如我所说的-我测试过这种方法,它工作-图像在picturebox中正确显示,源文件未锁定。超过-如果您查看
Image
类源(
EnsureSave
方法,该方法实际上从流中读取图像)-您将看到在
EnsureSave
完成后不需要打开流。所以我不知道为什么MSDN坚持在
Image.FromStream
completion之后打开流。它只起作用并不意味着它会继续起作用。如果文档没有提到它,我们可以假设它会起作用,但是当文档明确表示必须保持流的开放时,您应该保持流的开放。我害怕使用违反文档的东西,因为他们可以随时更改实现。从
FileStream
读取图像,而不是将文件内容复制到
MemoryStream
首先看起来稍微优雅一些。@AndyKorneyev优雅,是的。但是您需要在
图像的生存期内保持
文件流
处于打开状态。这与调用
Image.FromFile
相同。这对OP没什么帮助,那不行。克隆保留到原始文件的链接。@nyrguds ReferenceSource说:实际的克隆是由GDI+系统完成的,这也是原始文件的创建过程。这段代码什么也没说,因为您不知道
GdipCloneImage
@nyrguds中有什么内容,这就足够了:Image类不知道位图类的流或到原始文件的链接。怎么能在不知情的情况下复制链接?@nyrguds BTW:你测试过吗?我做到了,它像一个魔咒一样工作