Is there a way to capture the color of the screen pixel without taking screenshot C#?

Viewed 389

I am making a program that detects a sector of the screen to perform an action that I require and I am doing it through screenshot reviewing pixel by pixel to find the sector that I want to analyze and compare with the change that I want but I have a problem, I use a timer to taking screenshot every 20 times per second and the sentences in charge of taking the screenshot end in an exception that I don't understand at all, it works fine at times until the exception "ArgumentsException" appears and the message "Parameters are not valid", so I do not know what may be happening, I am supposed to be sending the correct parameters and I am even setting the sentences to null thinking that something was left out but no, the same thing continues and I do not understand why.

Now, I don't know if there is any other way to directly detect and without taking screenshots the pixels of the sector that I want to find since I see that there is a problem regarding the sentences to capture an image from the screen.

The code I use to take screenshots is:

screenCapture = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppRgb);
g = Graphics.FromImage(screenCapture);
g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, screenCapture.Size, CopyPixelOperation.SourceCopy);

Sometimes the problem is in the bitmap, other times it is the graphics that come out with the same problem, so can you recommend me for the purpose that I require?

1 Answers

Without taking a screenshot you can use the Win32 API GetPixel: https://www.pinvoke.net/default.aspx/gdi32/getpixel.html

  using System;
  using System.Drawing;
  using System.Runtime.InteropServices;
  sealed class Win32
  {
      [DllImport("user32.dll")]
      static extern IntPtr GetDC(IntPtr hwnd);

      [DllImport("user32.dll")]
      static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

      [DllImport("gdi32.dll")]
      static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);

      static public System.Drawing.Color GetPixelColor(int x, int y)
      {
       IntPtr hdc = GetDC(IntPtr.Zero);
       uint pixel = GetPixel(hdc, x, y);
       ReleaseDC(IntPtr.Zero, hdc);
       Color color = Color.FromArgb((int)(pixel & 0x000000FF),
                    (int)(pixel & 0x0000FF00) >> 8,
                    (int)(pixel & 0x00FF0000) >> 16);
       return color;
      }
   }

Alternatively consider Blit's as they're cheaper than screenshots, C# - Faster Alternatives to SetPixel and GetPixel for Bitmaps for Windows Forms App

Related