在C#中处理一个OpenFileDialog

本文关键字:一个 OpenFileDialog 处理 | 更新日期: 2023-09-27 18:27:08

我已经搜索了整个堆栈;溢出,但我找不到以下问题的答案:

当我使用OpenFileDialog时,我打开的文件会被阻止在程序外使用,直到我关闭程序。因此,如果我打开一个映像,则不允许在我的Windows中替换该映像;不再是Explorer。

我认为这是处理我的OpenFileDialog的一个问题,但我不确定如何解决它…

我的代码:

using (OpenFileDialog ofd = new OpenFileDialog())
{
    ofd.Title = "Open Image";
    ofd.Filter = "PNG Image(*.png|*.png" +
                 "|GIF Image(*.gif|*.gif" +
                 "|Bitmap Image(*.bmp|*.bmp" +
                 "|JPEG Compressed Image (*.jpg|*.jpg";
    if (ofd.ShowDialog() == DialogResult.OK)
    {
        pictureBox1.Image = new Bitmap(ofd.FileName);
    }
}

我原以为using块可以解决这个问题,但没有。。。它仍然被程序使用。我想在picturebox中加载图像,然后我希望图像再次可用(这样我就可以重命名、替换它等)。

在C#中处理一个OpenFileDialog

这与OpenFileDialog无关。不可能,因为对话框实际上并没有打开文件。它只允许用户选择要打开的文件,然后将该路径返回给您,以便您可以编写打开该文件的代码。此外,您通过使用using语句正确地处理了OpenFileDialog。

这里的问题来自于实际将文件ofd.FileName作为位图打开。使用接受路径字符串的位图构造函数重载时,磁盘上包含图像的文件将保持锁定状态,直到位图对象被释放。文件是这样说的:

该文件将保持锁定状态,直到位图被释放为止。

因为要将位图分配给pictureBox1.Image,所以只有在pictureBox1被释放后,位图对象才会被释放。因此,磁盘上的图像文件将保持锁定状态。

如果你想解锁文件,你要么需要制作位图的副本并处理原始图像,要么清除PictureBox并在完成后处理其先前的图像。

我理解您的问题,听起来您希望能够在继续在图片框中显示图像的同时更改磁盘上的图像文件。如果是这样的话,你需要复印一份。使用获取图像的构造函数重载来实现这一点,如下所示:

if (ofd.ShowDialog() == DialogResult.OK)
{
    // Load the image the user selected
    using (Image img = Image.FromFile(ofd.FileName))
    {
        // Create a copy of it
        Bitmap bmpCopy = new Bitmap(img);
        // Clear out the bitmap currently in the picture box,
        // if there is one.
        if (pictureBox1.Image != null)
        {
            pictureBox1.Image.Dispose();
        }
        // Assign the copy of the bitmap to the picture box.
        pictureBox1.Image = bmpCopy;
    }
}

如Chris所写,请尝试以下操作:

pictureBox1.Image = Image.FromStream(new MemoryStream(File.ReadAllBytes(old.FileName)));

它读取带有File.ReadAllBytes的所有文件,将其放入MemoryStream中,并将MemoryStream传递给Image静态初始化器。

相当于:

byte[] bytes = File.ReadAllBytes(old.FileName);
MemoryStream ms = new MemoryStream(bytes);
pictureBox1.Image = Image.FromStream(ms);

你不能丢弃MemoryStream!如果/当Image将被释放时,MemoryStream的终结器将启动(如果您没有对ms的其他引用),MemoryStream将被释放(注意,这不是立即发生的事情…这是GC运行时会发生的事情)

我发现最好的技术是使用file.ReadAllBytes()(打开和关闭文件)将文件读取到字节数组中,然后使用ImageConverter将字节数组转换为Image。例如,请参见此处:https://stackoverflow.com/a/16576471/253938

编辑:引用我上一篇文章中的一句话:"我尝试过的其他一些技术都不是最佳的,因为它们改变了像素的位深度(24位与32位)或忽略了图像的分辨率(dpi)。"

相关文章: