Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read the Color of a Screen Pixel

Okay, I am looking for a function or something that will read the color of a certain pixel on my monitor, and when that color is detected, another function will be enabled. I figure using RGB. All help appreciated. Thank You.

like image 387
Brandon Avatar asked Sep 27 '09 16:09

Brandon


People also ask

How do you read pixel colors?

With the get() function we can read the color of any pixel in our program window. We can specify which pixel we are interested in by using x and y coordinates as parameters. For example, color mycolor = get(100, 200); would grab the color of pixel 100, 200 and put that color into the mycolor variable.

How do I find out the RGB color of my monitor?

Open MS Paint (or any other image processing app) and paste the screenshot. Find the eyedropper tool and pick a color. Click “Edit colors” next to the color palette in MS Paint. Under the slider, you will see the RGB values of your current color.

What are the three color values of a pixel?

Thus, pixels in color images are represented by three values (r,g,b). The values indicate the intensity of red, green, and blue, respectively, needed to render the pixel on screen.


1 Answers

This is the most efficient: It grabs a pixel at the location of the cursor, and doesn't rely on only having one monitor.

using System; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Diagnostics;  namespace FormTest {     public partial class Form1 : Form     {         [DllImport("user32.dll")]         static extern bool GetCursorPos(ref Point lpPoint);          [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]         public static extern int BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);          public Form1()         {             InitializeComponent();         }          private void MouseMoveTimer_Tick(object sender, EventArgs e)         {             Point cursor = new Point();             GetCursorPos(ref cursor);              var c = GetColorAt(cursor);             this.BackColor = c;              if (c.R == c.G && c.G < 64 && c.B > 128)             {                 MessageBox.Show("Blue");             }         }          Bitmap screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb);         public Color GetColorAt(Point location)         {             using (Graphics gdest = Graphics.FromImage(screenPixel))             {                 using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero))                 {                     IntPtr hSrcDC = gsrc.GetHdc();                     IntPtr hDC = gdest.GetHdc();                     int retval = BitBlt(hDC, 0, 0, 1, 1, hSrcDC, location.X, location.Y, (int)CopyPixelOperation.SourceCopy);                     gdest.ReleaseHdc();                     gsrc.ReleaseHdc();                 }             }              return screenPixel.GetPixel(0, 0);         }     } } 

Now, obviously, you don't have to use the cursor's current location, but this is the general idea.

EDIT:

Given the above GetColorAt function you can poll a certain pixel on the screen in a safe, performance friendly way like this:

private void PollPixel(Point location, Color color) {     while(true)     {         var c = GetColorAt(location);          if (c.R == color.R && c.G == color.G && c.B == color.B)         {             DoAction();             return;         }          // By calling Thread.Sleep() without a parameter, we are signaling to the         // operating system that we only want to sleep long enough for other         // applications.  As soon as the other apps yield their CPU time, we will         // regain control.         Thread.Sleep()     } } 

You can wrap that in a Thread if you want, or execute it from a Console application. "Whatever suits your fancy," I guess.

like image 179
John Gietzen Avatar answered Oct 09 '22 11:10

John Gietzen