CMTV
CMTV

Reputation: 2851

Making screenshots very fast and out of memory

I am trying to make screenshots of my screen very fast.

So, I use this code in my main class

[STAThread]
static void Main(string[] args)
{
    int x = 1;
    int screenshotsAmount = 0;
    List<Bitmap> screenshots = new List<Bitmap>();
    while (x == 1)
    {
        screenshots.Add(FullsizeScreenshot.makeScreenshot());
        Clipboard.SetImage(screenshots[screenshotsAmount]);
        Console.WriteLine("Screenshot " + screenshotsAmount + " has been made and added to the Bitmap list!");
        screenshotsAmount++;
    }
}

And I have a method in my .dll, that creates screenshots

// Class for making standard screenshots
public struct FullsizeScreenshot
{

    // Making fullscreen screenshot
    public static Bitmap makeScreenshot() 
    {
        Bitmap screenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

            Graphics gfxScreenshot = Graphics.FromImage(screenshot);

            gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

            gfxScreenshot.Dispose();

            return screenshot;
    }
}

Everything works correct, but when the number of screenshots becomes bigger than 109, my program crash with System.ArgumentException

An unhandled exception of type "System.ArgumentException" in System.Drawing.dll Additional information: Invalid parameter.

This line throws it: gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy); or this: Bitmap screenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

I tried to use using (Bitmap screenshot....) and .Dispose(), but it doesn't work correct, because these classes (Bitmap and Graphics) are classes and they just create links instead of making copies. As a result, when I dispose the Bitmap in makeScreenshot() it broke the Bitmap in my List.

So, what should I do? Maybe I should make a copy, but I don't know how.

Upvotes: 1

Views: 2206

Answers (1)

weston
weston

Reputation: 54791

Suppose you have a display of 1920x1080, that's 2,073,600 pixels, there are 4 bytes per pixel in a PixelFormat.Format32bppArgb So that's 8,294,400 bytes, or around 8 MB. 109 images would be 872 MB. Surprised that's crashing there, but you get the idea, it's too much memory.

If you want to make an animated gif, think how large that's going to be, full screen? Well I hope you're not planing on that, that's not practical for a gif. After you take the screenshot, resize it down immediately to the target resolution so it takes less memory.

Upvotes: 1

Related Questions