2017-10-27 7 views
0

画面の一部をキャプチャしてズームする画面のズームを作成します。以下のコードは、画面をキャプチャしてPictureBoxで再生できるようになりました。しかし、私はプログラムを開いている間、私の記憶が成長し続けるというこの問題を抱えています。私は解放されないいくつかのリソースがなければならないと思うし、それを解放する方法を知らない。PictureBoxリソースのリリース

私はメディアプレーヤーのようにしていますが、ビデオを再生するのではなく、現在の画面の一部を再生します。

public partial class Form1 : Form 
{ 

    PictureBox picBox; 
    Bitmap bit; 
    Graphics g; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     picBox = pictureBox; 
    } 

    private void CopyScreen() 
    { 

     bit = new Bitmap(this.Width, this.Height); 
     g = Graphics.FromImage(bit as Image); 

     Point upperLeftSource = new Point(
      Screen.PrimaryScreen.Bounds.Width/2 - this.Width/2, 
      Screen.PrimaryScreen.Bounds.Height/2 - this.Height/2); 

     g.CopyFromScreen(upperLeftSource, new Point(0, 0), bit.Size); 

     picBox.Image = Image.FromHbitmap(bit.GetHbitmap()); 

     bit.Dispose(); 
     g.Dispose(); 
    } 

    private void timer_Tick(object sender, EventArgs e) 
    { 
     CopyScreen(); 
    } 
+0

https://stackoverflow.com/questions/1831732/c-sharp-picturebox-memory-releasing-problemを見てください –

+0

@mjwills動作しています...メモリはまだ成長し続けています –

+0

@mjwills私はタイマーの間隔を設定しました〜20になるので、メモリは非常に高速になります。たとえば、毎秒10MBのように。 –

答えて

1

問題は、あなたのGetHbitmapの使用、そしてあなたがPictureBoxに新しいImageを割り当てるときに、前のImage処分されていないという事実です。

https://msdn.microsoft.com/en-us/library/1dz311e4(v=vs.110).aspx状態は:

あなたは GDIビットマップオブジェクトが使用するメモリを解放するためにGDI DeleteObjectのメソッドを呼び出すための責任があります。 (あなたがやっていません)

は(とDispose前のImageに)GetHbitmapコールの必要性を回避するために、コードを変更することを検討:

private void CopyScreen() 
{ 
    bit = new Bitmap(this.Width, this.Height); 
    g = Graphics.FromImage(bit); 

    Point upperLeftSource = new Point(
     Screen.PrimaryScreen.Bounds.Width/2 - this.Width/2, 
     Screen.PrimaryScreen.Bounds.Height/2 - this.Height/2); 

    g.CopyFromScreen(upperLeftSource, new Point(0, 0), bit.Size); 

    var oldImage = picBox.Image; 
    picBox.Image = bit; 
    oldImage?.Dispose(); 

    g.Dispose(); 
} 

を簡単にするためにさらに、クラスの先頭で宣言したフィールドを削除して使用してください:

private void CopyScreen() 
{ 
    var picBox = pictureBox; 
    var bit = new Bitmap(this.Width, this.Height); 

    using (var g = Graphics.FromImage(bit)) 
    { 
     var upperLeftSource = new Point(
      Screen.PrimaryScreen.Bounds.Width/2 - this.Width/2, 
      Screen.PrimaryScreen.Bounds.Height/2 - this.Height/2); 

     g.CopyFromScreen(upperLeftSource, new Point(0, 0), bit.Size); 

     var oldImage = picBox.Image; 
     picBox.Image = bit; 
     oldImage?.Dispose(); 
    } 
} 
+1

時間をかけて助けてくれてありがとう!あなたと自分自身に貢献しているすべての人々が、スタックオーバーフローをプログラマにとって最良の場所にします。私はあなたに感心し、できる限り私は他人を助けるために最善を尽くします。私の貧しい英語を残念に思います。 –

関連する問題