9

我已经在 PictureBox 控件中有一个图像,现在我想向它传递一个新图像。

会发生什么,是 allpication Disposes(我发现了一个异常:“参数无效”)。

这是我的代码:

            using (Image img = Image.FromFile(open.FileName))
            {
                part.Picture = img;
                pictureBox1.InitialImage = null;
                pictureBox1.Image = img;
            }    

因此,当代码退出该方法时,它会直接 Displose 这个和主窗体。我仅在 Form1 启动的行上捕获异常。在这一点上,没有任何例外。pictureBox 正在绘画(在 Paint 事件中)时一定有问题,但我没有对此感到满意。

我真的不知道如何解决这个问题。我什至尝试使用清除所有资源(通过调用垃圾收集),但似乎没有任何效果。


还有一件事:“部分”是列表的引用,所以当我尝试删除当前图像(用新图像替换它)时,我遇到了另一个异常,例如:

“该进程无法访问该文件,因为它正在被另一个进程使用”。


这是否与第一个异常有关(当新图像未在图片框中绘制时)?

4

4 回答 4

13

正如 Reed 所指出的,一旦您退出 using() 语句,您从 open.Filename 中提取的图像就会被释放。您的图片框仍在内存中引用此图像,因此当它被处理时,您也会丢失存储在图片框中的内容。

您真正需要的是您正在提取的图像的唯一副本。

    using (Image sourceImg = Image.FromFile(open.Filename))
    {
        Image clonedImg = new Bitmap(sourceImg.Width, sourceImg.Height, PixelFormat.Format32bppArgb);
        using (var copy = Graphics.FromImage(clonedImg))
        {
            copy.DrawImage(sourceImg, 0, 0);
        }
        pictureBox1.InitialImage = null;
        pictureBox1.Image = clonedImg;
    }

这样,您的文件将在您退出此块后立即解锁,并且您将在图片框中保留图像的唯一副本。

于 2012-10-01T21:15:36.297 回答
5

问题是,在这段代码执行之后,pictureBox1.Image它指的是一个Image已经被处理的。

如果您不将Image创建包装在 a 中using,它应该可以解决您的问题。

Image img = Image.FromFile(open.FileName);
part.Picture = img;
pictureBox1.InitialImage = null;
pictureBox1.Image = img; // You can't dispose of this, or it won't be valid when PictureBox uses it!
于 2012-10-01T20:33:43.077 回答
0

是的,这现在有效,但奇怪的是,我几乎发誓我也尝试过这种方式。好吧,没关系,只是它有效。困扰我的还有其他事情,我认为这与您的代码相同,但它不起作用,它再次尝试 Dispose 应用程序(同样的例外)。这是一个示例代码:

using(Image img = Image.FromFile(open.FileName))
{
   part.Picture = img; 
}
pictureBox1.InitialImage = null;
pictureBox1.Image = part.Picture;  //Picture  is a propery in a class

现在我将一个实际图像传递到一个通用列表中,并尝试从中将新图像分配给图片框,但是,正如我所说,再次引发异常(并且应用程序终止)。为什么?

于 2012-10-01T20:48:20.573 回答
0

您还可以执行以下操作,创建一个加载图像然后将其传递回图像控件的方法,例如,这就是我想填充图像控件时使用的方法

我有一个带有 3 个要加载的不同图像的 Windows 窗体,但我只显示一个的代码,因为我为所有 3 个图像控件调用相同的方法

    #region Codes for browsing for a picture
    /// <summary>
    /// this.picStudent the name of the Image Control
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnStudentPic_Click(object sender, EventArgs e)
    {
        Image picture = (Image)BrowseForPicture();
        this.picStudent.Image = picture;
        this.picStudent.SizeMode = PictureBoxSizeMode.StretchImage;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    private Bitmap BrowseForPicture()
    {
       // Bitmap picture = null;

        try
        {
            if (this.fdlgStudentPic.ShowDialog() == DialogResult.OK)
            {
                byte[] imageBytes = File.ReadAllBytes(this.fdlgStudentPic.FileName);
                StudentPic = new Bitmap( this.fdlgStudentPic.FileName);
                StuInfo.StudentPic = imageBytes;
            }
            else
            {
                StudentPic = Properties.Resources.NoPhotoAvailable;
            }
        }
        catch (Exception)
        {
            MessageBox.Show("That was not a picture.", "Browse for picture");
            StudentPic = this.BrowseForPicture();
        }

        return StudentPic;
    }
    #endregion
于 2012-10-01T20:46:28.577 回答