C# 如何在不使用太多内存的情况下将屏幕截图分配给picturebox

C# 如何在不使用太多内存的情况下将屏幕截图分配给picturebox,c#,.net,bitmap,C#,.net,Bitmap,所以我有一个代码,在其中我创建了一个位图和图形,并使用CopyFromScreen方法拍摄了一个屏幕截图,然后我继续将其分配给picturebox。它在一根线里面,所以它一直在走。问题是RAM消耗一直在增加,如果我尝试使用graphics.Dispose和bitmap.Dispose,它将给出一个错误,因为pictureBox在引用被删除时不会显示任何内容。我已经尝试将位图克隆到另一个位图并处理原始位图,但结果是一样的,RAM仍然上升 与其说这是一个有用的项目,不如说这是一个问题,但我的想法是p

所以我有一个代码,在其中我创建了一个位图和图形,并使用CopyFromScreen方法拍摄了一个屏幕截图,然后我继续将其分配给picturebox。它在一根线里面,所以它一直在走。问题是RAM消耗一直在增加,如果我尝试使用graphics.Dispose和bitmap.Dispose,它将给出一个错误,因为pictureBox在引用被删除时不会显示任何内容。我已经尝试将位图克隆到另一个位图并处理原始位图,但结果是一样的,RAM仍然上升

与其说这是一个有用的项目,不如说这是一个问题,但我的想法是picturebox可以实时复制整个屏幕

我怎样才能避开这件事

代码示例:

while (run)
        {

            bitmap1 = new Bitmap(1920, 1080);
            g = Graphics.FromImage(bitmap1);

            g.CopyFromScreen(0, 0, 0, 0, size);

            form.setPictureBox1(bitmap1);
            
            
            g.Dispose();
            bitmap1.Dispose();
            GC.SuppressFinalize(this);
            

            Thread.Sleep(500);

        }

应释放所有本机对象。这包括图形和位图对象。您的代码失败,因为您在截图后仍希望使用位图

如果您知道自己有一个固定大小,那么简单的方法是只创建一次位图,然后在每个屏幕截图中重复使用它:

Bitmap myBitmap = new Bitmap(1920, 1080); // Make sure bitmap is disposed when the form is disposed.
public MyForm()
{
    myPictureBox.Image = myBitmap;
    ...
}
public void TakeScreenshot()
{
    using(var g = Graphics.FromImage(myBitmap))
    {
          g.CopyFromScreen(0, 0, 0, 0, myBitmap.Size);
    }
    myPictureBox.Invalidate();
 }

另一种方法是检查picturebox是否已经有图像,并在替换图像之前对其进行处理。

正如John所建议的,您应该在创建新图像之前对旧图像进行处理。您还可以处理图形

下面是一个快速示例,展示了一种方法:

private bool run = true;

private void Form1_Load(object sender, EventArgs e)
{
    Thread T = new Thread(new ThreadStart(Foo));
    T.IsBackground = true;
    T.Start();
}

private void Foo()
{
    Bitmap bmp;
    Size size = Screen.PrimaryScreen.Bounds.Size;
    while (run)
    {
        bmp = (Bitmap)pictureBox1.Image;
        pictureBox1.Image = null;
        if (bmp != null)
        {
            bmp.Dispose();
        }

        bmp = new Bitmap(1920, 1080);
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.CopyFromScreen(0, 0, 0, 0, size);
        }                 
        pictureBox1.Image = bmp;

        Thread.Sleep(500);
    }
}

想想这个:我给你50美元花。你到了商店,把它放在柜台上。在收银员拿走它之前,我抢走了它并点燃了它。你还能花掉那50美元吗?不,你在做同样的事情。一旦将图像交给picturebox,您就要处理该图像。请注意,当您将其分配给picturebox时,您没有制作副本,因为它是同一图像。处理旧映像不是更有意义吗?Microsoft有一个完整的代码示例。我现在就得到了,非常感谢!主要的问题是我在创建很多位图的时候,我写的代码在我的脑海里是有意义的,哈哈。我明白了,非常感谢!Foo中的操作不会抱怨跨线程操作吗?很确定你需要调用它。@nyrguds,试试看,告诉我你的结果。我敢肯定你会感到惊讶的…@Idle\u Mind这很难回答我的问题。仅仅因为一次测试没有出现错误就假设一切都正常运行,这绝不是一个好主意。尝试不处理bmp,并运行几分钟。它可能会继续工作。但这并不意味着没有什么问题。