9

PictureBoxコントロール内にすでに画像があり、新しい画像を渡したいと思います。

何が起こるかというと、allpication Disposesです(そして私は例外をキャッチします:「パラメーターが無効です」)。

これは私のコードです:

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

したがって、コードがメソッドの外に出ると、このフォームとメインフォームのDisploseに直行します。Form1が開始された行でのみ例外をキャッチします。これには、これまでに何の例外もありません。pictureBoxがペイントしている間(Paintイベント内)は何か問題があるはずですが、私はそれに責任を負いません。

私は本当にこの問題を解決する方法についてこれ以上の手がかりを持っていません。(ガベージコレクションを呼び出して)すべてのリソースをクリアするために使用しようとしましたが、何も機能していないようです。


もう1つ、「part」はリストの参照であるため、現在の画像を削除しようとすると(新しい画像に置き換えるため)、次のような別の例外が発生します。

「別のプロセスによって使用されているため、プロセスはファイルにアクセスできません」。


これは、最初の例外(新しい画像がpictureBoxにペイントされていない場合)と関係がありますか?

4

4 に答える 4

13

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

このように、このブロックを終了するとすぐにファイルのロックが解除され、画像の一意のコピーが画像ボックスに保持されます。

于 2012-10-01T21:15:36.297 に答える
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!
于 2012-10-01T20:33:43.077 に答える
0

次のようなこともできます。画像を読み込んでから画像コントロールに戻すメソッドを作成します。たとえば、これは画像を入力するときに使用しているものですCtrl

ロードしたい3つの異なる画像を含むWindowsフォームがありますが、3つの画像コントロールすべてに対して同じメソッドを呼び出すため、1つのコードのみを表示しています。

    #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 に答える
0

はい、これは現在機能していますが、奇妙なことに、私もこの方法を試したことを誓います。わかりました、気にしないでください、それが機能することだけです。私を悩ませているのは他のことでもあります。これは私の意見ではあなたのコードと同じですが、機能せず、アプリケーションを破棄しようとしています(同じ例外を除いて)。これはサンプルコードです:

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に割り当てようとしますが、ここでも、例外がスローされます(そしてアプリケーションは終了します)。なんで?

于 2012-10-01T20:48:20.573 に答える