Как читать цвет пикселя экрана

Хорошо, я ищу функцию или что-то, что будет читать цвет определенного пикселя на моем мониторе, и когда этот цвет будет обнаружен, будет включена другая функция. Я использую RGB. Вся помощь была оценена. Спасибо.

Это наиболее эффективно: он захватывает пиксель в месте расположения курсора и не полагается только на один монитор.

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 (cR == cG && cG < 64 && cB > 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); } } } 

Теперь, очевидно, вам не нужно использовать текущее местоположение курсора, но это общая идея.

РЕДАКТИРОВАТЬ:

Учитывая вышеприведенную функцию GetColorAt вы можете опросить определенный пиксель на экране безопасным, удобным для производительности способом:

 private void PollPixel(Point location, Color color) { while(true) { var c = GetColorAt(location); if (cR == color.R && cG == color.G && cB == 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() } } в private void PollPixel(Point location, Color color) { while(true) { var c = GetColorAt(location); if (cR == color.R && cG == color.G && cB == 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() } } 

Вы можете обернуть это в streamе, если хотите, или выполнить его из консольного приложения. «Что бы ни нравилось твоей фантазии», я думаю.

В большинстве ответов здесь используется тот же источник этого пикселя (рабочий стол постоянного тока).
Ключевой функцией является GetPixel .

 [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr GetDesktopWindow(); [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr GetWindowDC(IntPtr window); [DllImport("gdi32.dll", SetLastError = true)] public static extern uint GetPixel(IntPtr dc, int x, int y); [DllImport("user32.dll", SetLastError = true)] public static extern int ReleaseDC(IntPtr window, IntPtr dc); public static Color GetColorAt(int x, int y) { IntPtr desk = GetDesktopWindow(); IntPtr dc = GetWindowDC(desk); int a = (int) GetPixel(dc, x, y); ReleaseDC(desk, dc); return Color.FromArgb(255, (a >> 0) & 0xff, (a >> 8) & 0xff, (a >> 16) & 0xff); } 

Я думаю, что это самый чистый и быстрый способ.

Примечание .

Если вы изменили размер текста по умолчанию среди параметров экрана в Windows, чтобы повысить читаемость на дисплее с высоким разрешением, параметры координат GetPixel () необходимо отрегулировать одинаково. Например, если местоположение курсора (x, y) с 150% размера текста в Windows 7, вам нужно вызвать GetPixel (x * 1.5, y * 1.5), чтобы получить цвет пикселя под курсором.

Пожалуйста, проверьте две разные функции, которые я использовал в одном из моих предыдущих проектов:

1) Эта функция выполняет моментальный снимок рабочего стола

 private void CaptureScreenAndSave(string strSavePath) { //SetTitle("Capturing Screen..."); Bitmap bmpScreenshot; Graphics gfxScreenshot; bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height,System.Drawing.Imaging.PixelFormat.Format32bppArgb); gfxScreenshot = Graphics.FromImage(bmpScreenshot); gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy); MemoryStream msIn = new MemoryStream(); bmpScreenshot.Save(msIn, System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[0], null); msIn.Close(); byte[] buf = msIn.ToArray(); MemoryStream msOut = new MemoryStream(); msOut.Write(buf, 0, buf.Length); msOut.Position = 0; Bitmap bmpOut = new Bitmap(msOut); try { bmpOut.Save(strSavePath, System.Drawing.Imaging.ImageFormat.Bmp); //SetTitle("Capturing Screen Image Saved..."); } catch (Exception exp) { } finally { msOut.Close(); } } 

2) Эта функция принимает изображение во входе и вычисляет RGB среднее значение диапазона пикселей.

 double GetRGBAverageForPixelRange( int istartRange, int iEndRange, Bitmap oBitmap ) { double dRetnVal = 0 ; Color oTempColor ; int i, j ; for( int iCounter = istartRange ; iCounter < iEndRange ; iCounter++ ) { i = (iCounter % (oBitmap.Width)); j = ( iCounter / ( oBitmap.Width ) ) ; if (i >= 0 && j >= 0 && i < oBitmap.Width && j < oBitmap.Height ) { oTempColor = oBitmap.GetPixel(i, j); dRetnVal = dRetnVal + oTempColor.ToArgb(); } } return dRetnVal ; } 

Эти две функции вместе могут решить вашу проблему. Счастливое кодирование 🙂

EDIT : Обратите внимание, что GetPixel работает очень медленно. Я буду думать дважды, прежде чем использовать его.

Насколько я знаю, самый простой способ сделать это:

  1. сделать снимок экрана
  2. посмотрите на bitmap и получите цвет пикселя

редактировать

Вероятно, нет способа «подождать», пока пиксель не изменится на определенный цвет. Ваша программа, вероятно, должна будет просто зацикливаться и проверять ее каждый раз, пока не увидит цвет.

Например:

 while(!IsPixelColor(x, y, color)) { //probably best to add a sleep here so your program doesn't use too much CPU } DoAction(); 

EDIT 2

Вот пример кода, который вы можете изменить. Этот код просто изменяет цвет метки на основе текущего цвета в данном пикселе. Этот код позволяет избежать упомянутой утечки рукоятки.

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; using System.Runtime.InteropServices; namespace WindowsFormsApplication1 { public partial class Form1 : Form { [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); Thread t; int x, y; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { x = 20; y = 50; t = new Thread(update); t.Start(); } private void update() { Bitmap screenCopy = new Bitmap(1, 1); using (Graphics gdest = Graphics.FromImage(screenCopy)) { while (true) { //g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(256, 256)); using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero)) { IntPtr hSrcDC = gsrc.GetHdc(); IntPtr hDC = gdest.GetHdc(); int retval = BitBlt(hDC, 0, 0, 1, 1, hSrcDC, x, y, (int)CopyPixelOperation.SourceCopy); gdest.ReleaseHdc(); gsrc.ReleaseHdc(); } Color c = Color.FromArgb(screenCopy.GetPixel(0, 0).ToArgb()); label1.ForeColor = c; } } } } 

}

Эта функция короче и может достичь того же результата, используя System.Drawing , без Pinvoke.

 Bitmap bmp = new Bitmap(1, 1); Color GetColorAt(int x, int y) { Rectangle bounds = new Rectangle(x, y, 1, 1); using (Graphics g = Graphics.FromImage(bmp)) g.CopyFromScreen(bounds.Location, Point.Empty, bounds.Size); return bmp.GetPixel(0, 0); } 
  • Обновление C # GUI и asynchronous serial port
  • Сохранить настройки в VB.Net или C #
  • Элементы управления в форме контейнера попадают в дочернюю форму?
  • Опираясь на элементы управления внутри панели (C # WinForms)
  • Установщик WiX msi не устанавливает приложение Winform, созданное с помощью Visual Studio 2017
  • Как отключить некоторые даты в элементе управления DateTimePicker?
  • Как изменить цвет шрифта отключенного TextBox?
  • Как сделать текстовое поле, которое принимает только числа?
  • Как установить UserControl в Visual Studio toolBox
  • Событие, когда окно максимизируется / не максимизируется
  • Бесплатный / открытый редактор исходного кода. Интерфейс пользовательского интерфейса для .Net
  • Давайте будем гением компьютера.