2

我已经搜索了整个 Stack Overflow,但我找不到以下问题的答案:

当我使用我的OpenFileDialog时,我打开的文件会被阻止在我的程序之外使用,直到我关闭我的程序。因此,如果我打开一个图像,我将不再被允许在我的Windows 资源管理器中替换该图像。

我认为这是处理我的 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块可以解决这个问题,但不......它仍然被程序使用。我想将图像加载到图片框中,然后我希望图像再次可用(所以我可以重命名它,替换它等等......)。

4

3 回答 3

5

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

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

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

因为您将位图分配给pictureBox1.Image,所以在释放之前不会释放 Bitmap 对象pictureBox1。因此,您在磁盘上的图像文件将保持锁定状态。

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

据我了解您的问题,听起来您希望能够更改磁盘上的图像文件,同时继续在图片框中显示图像。如果是这种情况,您将需要制作副本。使用带有 Image 的构造函数重载来执行此操作,如下所示:

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;
    }
}
于 2013-08-11T13:02:02.343 回答
1

正如克里斯所写,尝试类似:

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

它使用 读取所有文件File.ReadAllBytes,将其放入 aMemoryStream并将 传递MemoryStreamImage静态初始化程序。

相当于:

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

您不得丢弃MemoryStream! 如果/当Image将被处置时,终结MemoryStream器将启动(如果您没有其他对 的引用ms)并且MemoryStream将被处置(请注意,这不是立即发生的事情......这是会发生的事情GC何时运行)

于 2013-08-11T13:09:35.960 回答
0

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

编辑:引用我之前的帖子:“我尝试过的其他一些技术不是最佳的,因为它们改变了像素的位深度(24 位与 32 位)或忽略了图像的分辨率( dpi)。”

于 2013-08-11T13:22:20.013 回答