How does the Graphics CopyFromScreen method copy to a bitmap?

private void startBot_Click(object sender, EventArgs e)
{
        Bitmap bmpScreenshot = Screenshot();
        this.BackgroundImage = bmpScreenshot;
}

private Bitmap Screenshot()
{

    // This is where we will store a snapshot of the screen
    Bitmap bmpScreenshot = 
        new Bitmap(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height);

    // Creates a graphic object so we can draw the screen in the bitmap (bmpScreenshot);
    Graphics g = Graphics.FromImage(bmpScreenshot);

    // Copy from screen into the bitmap we created
    g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);

    // Return the screenshot
    return bmpScreenshot;
}

      

I recently played with C # and I'm just following some tutorial, I just don't understand how if I erase Graphics g

it would not put the image as a background, but in the absence of point, the code assigns any relationship between the variables except Graphics g = Graphics.FromImage(bmpScreenshot)

then g

some parameters are given, but then we return bmpScreenshot

, which just doesn't make any sense, I would expect to g

be returned

+3


source to share


2 answers


Devices that can display graphics are virtualized in Windows. The concept is called "device context" in winapi, base view is "handle". The Graphics class wraps this handle; it does not store pixels itself. Notice the way Graphics.GetHdc (), the way to access this handle.

The class otherwise simply contains drawing methods that draw graphics output to the device represented by this handle. Actual devices can be screen, printer, metafile, bitmap. With the great advantage of your own code, it can be used to produce products wherever you want. This way, printing is as easy as drawing it on the screen or drawing to a bitmap that you store in a file.

Thus, by calling Graphics.FromImage (), you are binding the Graphics object to the bitmap. All of its drawing methods actually specify the pixels in the bitmap. Like CopyFromScreen (), it simply copies the pixels from the display framebuffer to the device context, effectively setting the pixels in the bitmap. So the expected return value of this code is the actual bitmap. The Graphics must be disposed of before this happens as it is no longer useful. Or, in other words, the base descriptor must be released in order for the operating system to deactivate its own resources to represent the device context.



This is a bug in the code snippet. Repeated calls to this method can easily crash the program when Windows refuses to create more device contexts. And the garbage collector won't catch up fast enough otherwise. It should be written as:

  using (var g = Graphics.FromImage(bmpScreenshot)) {
      g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);
      return bmpScreenshot;
  }

      

+7


source


It is understood that it Graphics g = Graphics.FromImage(bmpScreenshot)

creates a graphics context for drawing into the image, which was passed as an argument ( bmpScreenshot

).

So, after creating the graphical content:
Graphics g = Graphics.FromImage(bmpScreenshot)

When copying from the screen:
g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);



It controls a raster picture bmpScreenshot

, which Graphics g

contains a link.

From the documentation :

image [in]:
   Type: Image *

A pointer to an image object to associate with the new Graphics object.

0


source







All Articles