Hi,

I was wondering how I can get the coordinates of a specific color from a window? Is it possible.

I did some research, but I only found to get a color from coordinates, but I need it the other way around.

Atm I have this, I don't know if it is right, cause I usually program in java.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ConsoleApplication2
{
    class Program
    {

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", EntryPoint = "GetDC")]
        public static extern IntPtr GetDC(IntPtr ptr);
            
        static void Main(string[] args)
        {

            IntPtr nWnd = FindWindow("","DutchLeader - Uitnodigingen - Windows Internet Explorer");
            if (nWnd != IntPtr.Zero)
            {
                IntPtr dcWindow = GetDC(nWnd);
                //Here should come the code to get the coordinates from the color pixel
            }
            else
            {
                Console.WriteLine("Window niet gevonden");
            }
        }
    }
}

The second problem is that he can't findow the window. The window he needs to get, can be seen in photo which is in attachment.

Grtz

Dani AI

Generated

Three-step summary: 1) reliably get the window handle (FindWindow needs an exact class/title; for partial matches use EnumWindows or FindWindowEx to search children), 2) capture the window into a Bitmap (either copy the DC with BitBlt or ask the window to render itself with PrintWindow), and 3) scan the bitmap using LockBits (far faster than Bitmap.GetPixel). These are the general building blocks to find the X,Y coordinates for a given RGB value. (learn.microsoft.com)

Practical notes and pitfalls: ’s “window niet gevonden” usually means the title/class string didn’t match; use EnumWindows + GetWindowText and check for substrings or the class name (Spy++ or FindWindowEx helps). If the target app draws with layered/alpha surfaces or GPU-accelerated content you may not get pixels with a plain BitBlt — PrintWindow or OS-specific layered-window APIs are alternatives, and some layered windows are updated with UpdateLayeredWindow which affects capture results. Also be clear whether you want client coordinates or screen coordinates (use ClientToScreen/ScreenToClient to convert). (learn.microsoft.com)

Fast, practical C# approach (capture + scan). Use PrintWindow to get a bitmap and then LockBits+Marshal.Copy to scan with a small tolerance. This returns the first match; collecting all matches is the same loop but add points to a list.

// P/Invoke
[DllImport("user32.dll")] static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);
[DllImport("user32.dll")] static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
[StructLayout(LayoutKind.Sequential)] struct RECT { public int Left, Top, Right, Bottom; }

// Capture
Bitmap CaptureWindow(IntPtr hwnd) {
  GetWindowRect(hwnd, out RECT r);
  int w = r.Right - r.Left, h = r.Bottom - r.Top;
  var bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb);
  using (Graphics g = Graphics.FromImage(bmp)) {
    IntPtr hdc = g.GetHdc();
    PrintWindow(hwnd, hdc, 0);
    g.ReleaseHdc(hdc);
  }
  return bmp;
}

// Scan (first-match, with tolerance)
Point? FindColor(Bitmap bmp, Color target, int tol = 0) {
  var data = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
  try {
    int bytes = Math.Abs(data.Stride) * bmp.Height;
    byte[] buf = new byte[bytes];
    Marshal.Copy(data.Scan0, buf, 0, bytes);
    for (int y=0; y<bmp.Height; y++) {
      int row = y * data.Stride;
      for (int x=0; x<bmp.Width; x++) {
        int i = row + x*4;
        if (Math.Abs(buf[i+2]-target.R)<=tol && Math.Abs(buf[i+1]-target.G)<=tol && Math.Abs(buf[i+0]-target.B)<=tol)
          return new Point(x, y);
      }
    }
  } finally { bmp.UnlockBits(data); }
  return null;
}

As suggested, looping every pixel is correct in principle, but LockBits is much faster than GetPixel. As noted, expect multiple matches for common colors—either return the first match or accumulate a list and post-process (clustering, bounding boxes, or tolerance) depending on your use case. For authoritative API details see the linked Microsoft docs above. (learn.microsoft.com)

Recommended Answers

All 5 Replies

Refer this links

I think you probably misunderstood me. What I need is when I define the RGB values, the program should look for them and give me the coordinates of where it is found. Me/The program doesn't know a coordinate, it needs to search for it.

For example:

Red: 85
Green: 23
Blue: 240

Then program needs to search of the window (like in code)

A BitMap has a GetPixel method which returns a Color struct for the Color at coordinates X Y in the Bitmap. A Color struct can Compare one Color with another. So loop through every pixel of your bitmap and test for your color. If found you got your desired position.

There is a problem with this, very seldom will there be only 1 pixel of a particular color anywhere, It is very l likely that you will get hundreds of coordinates with even an unpopular color as many images contain millions of colors to make up and image.

but I digress a good approach would be to capture the entire screen as a bitmap (assuming you want screen coordinates) and then loop through that bitmap using getpixel and compare its color to your color, and then add that coordinate to your List of coordinates.

if you just wanted to look in a particular window, you can still screen cap the whole screen but just loop through a rectangle that is bound to that windows position on screen.


although, I can't see the use for this. Best of luck.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.