问题
I want to make a screen zoomer that captures a part of the screen and zoom it. The code below can now capture the screen and play it in a PictureBox. But I have this problem that my memory keeps growing while I open the program. I think there must be some resources that are not released and I don't know How to release it.
I'm making it like a media player, but instead of playing videos, it plays a part of the current screen.
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();
}
回答1:
The issue is with your use of GetHbitmap
, and the fact that you aren't disposing of the previous Image
when you assign a new Image
to the PictureBox
.
https://msdn.microsoft.com/en-us/library/1dz311e4(v=vs.110).aspx states:
You are responsible for calling the GDI DeleteObject method to free the memory used by the GDI bitmap object.
(which you aren't doing)
Consider changing the code to avoid the need for the GetHbitmap
call (and to Dispose
the previous Image
):
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();
}
To simplify it further, remove the fields you have declared at the top of the class, and just use:
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();
}
}
来源:https://stackoverflow.com/questions/46972162/picturebox-resources-release