例外:参数无效(将新图像传递给pictureBox时)

时间:2012-10-01 20:31:51

标签: c# image dispose

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

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

这是我的代码:

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

因此,当代码退出该方法时,它将直接显示为此主表单的Displose。我只在Form1启动的行上捕获异常。在这个问题上,没有什么可以解除的。 当pictureBox正在绘画时(在Paint事件中),它一定是错误的,但我并没有被它所吸引。

我真的不知道如何解决这个问题。我甚至试图用来清除所有资源(通过调用垃圾收集),但似乎没有任何工作。


还有一件事:“part”是List的引用,所以当我尝试删除当前图像(用新图像替换它)时,我得到了另一个例外,例如:

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


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

4 个答案:

答案 0 :(得分:9)

正如Reed所说,你从open.Filename中提取的图像在你退出using()语句后被处理掉了。您的图片框仍然在内存中引用此图像,因此当它被丢弃时,您也会丢失图片框中存储的内容。

您真正需要的是您正在拉动的图像的唯一副本。

    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;
    }

这样一旦您退出此区块,您的文件就会被解锁,并且您将在图片框中保留图像的唯一副本。

答案 1 :(得分:5)

问题是,在执行此代码后,pictureBox1.Image指的是已被处置的Image

如果您未将Image创作包装在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!

答案 2 :(得分:0)

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

我有一个带有3个不同图像的窗体,我想加载但我只显示One的代码,因为我为所有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

答案 3 :(得分: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

现在我将一个实际图像传递给一个通用列表,并尝试从中将新图像分配给pictureBox,但是,正如我所说的那样,抛出异常(应用程序终止)。 为什么呢?