Search code examples
c#wpfimage-processingbitmapgetpixel

Getting the coordinates from a point from an image


I am creating a program that can print out the x- & y- Coordinates from a certain pixel. There is a function like 'GetPixel', this will however get the RGB codes from a given coordinate. What I want is just the vice versa, so I have already the RGB codes and now I'm doing a threshold through my Image to know whether it contains a Color pixel that I desired or not.

This is my code:

So firstly I will upload an image:

    public BitmapImage bitmap;

    public void hochladen_Click(object sender, EventArgs e)
    {
        // Create OpenFileDialog 
        Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();

        // Set filter for file extension and default file extension 
        dlg.DefaultExt = ".bmp";
        dlg.Filter = "BMP Files (*.bmp)|*.bmp";

        // Get the selected file name and display in a TextBox 
        if (dlg.ShowDialog() == true)
       { 
            // Open document 
            string filename = dlg.FileName;
            bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = new Uri(filename);
            bitmap.EndInit();
            image.Source = bitmap;
        }
    }

Then when I click a button in my application, it should do a threshold from my Image, and I am going to detect a red Point (R = 255, G = B = 0)

    public Color c;

    private void detektieren_Click(object sender, RoutedEventArgs e)
    {
        double x = bitmap.Width;
        double y = bitmap.Height;
        bl.Content = x + "x" + y;

So from this Point on, it shouldn't be difficult to find the coordinate:

        for (int i = 0; i < x; i++)
        {
            for (int j = 0; i < j; j++)
            {
                if (c.R == 255 && c.G == 0 && c.B == 0)
                {
                    //
                }
            }
        }
    }

Anyone has idea? Thanks in advance.


Solution

  • Finding pixels matching a RGB value of course may return many pixels, try the following code to get all the pixels represented by Point structure:

    public Point[] GetPixelsFromRGB(byte[] rgbData, int stride, Color colorToFind){
      int k = stride/4;
      return rgbData.Select((x,i)=>new{x,i})
                    .GroupBy(a=>a.i/4,(key,a)=>a.ToArray())
                    .Where(g=>g[0].x == colorToFind.Red &&
                              g[1].x == colorToFind.Green &&
                              g[2].x == colorToFind.Blue && g[3].x == 255)
                    .Select(g=> new Point(g[0].i%k, g[0].i / k)).ToArray();
    }
    //Use this method to get the rgbData
    int stride = bitmap.PixelWidth * 4;
    byte[] rgbData = new byte[stride * bitmap.PixelHeight];
    bitmap.CopyPixels(rgbData, stride, 0);
    //then call the method above:
    var pixels = GetPixelsFromRGB(rgbData, stride, Colors.Red);
    

    Note that the code above has not been tested, I just typed directly into the answer editor.