Determine color of a pixel in a winforms application

前端 未结 3 1654
说谎
说谎 2021-01-06 15:16

I\'d like to be able to determine the backgroundcolor of a winform at a certain point on the screen, so I can take some action depending on that particular color. Sadly the

3条回答
  •  孤街浪徒
    2021-01-06 16:00

    This is a slightly different take on the other answers already provided as you've only stated that you want to determine the "color" but have not explicitly stated that you wanted the RGB values.

    This distinction is necessary because there may be variations to a colour that are imperceptible to the human eye. For example let's assume that you are interested in detecting the colour "blue". The values (5, 5, 240) and (10, 10, 255) are only very subtly different from (0, 0, 255). In fact, the difference is so subtle that you'd need to compare the colour swatches side by side to tell them apart and even then it depends on the quality of your monitor. They're subtly different on my desktop monitor but are indistinguishable on my laptop. To cut the long story short, RGB values are a bad way of determining colour.

    There are numerous methods to aid in calculating the difference between colours, the most common being the Delta-E method. However, this may be over kill if you just want a quick and dirty method. Convert RGB space into HSV and use the difference in hue to determine the colour. Modifying Amen's example, you get the following:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Drawing;
    
    class CursorHue
        {
            [DllImport("gdi32")]
            public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos);
    
            public static float GetHue(Point p)
            {           
                long color = GetPixel(dc, p.X, p.Y);
                Color cc = Color.FromArgb((int)color);
                return cc.GetHue();
            }
        }
    

    Pure blue has a hue value of 240. The previous examples (5, 5, 240) and (10, 10, 255) both have a hue of 240. This is good news as it means that hue is a measure that is fairly tolerant to RGB differences, and the difference is also quick to calculate (i.e. just take the absolute difference in the hue values). At this point, we should also introduce another parameter which governs acceptable tolerance to colour difference. A 15 degree hue tolerance will make the system fairly robust.

    Here's sample code that compares two colours to determine whether they are acceptably similar

    public static bool AreSimilar(Color c1, Color c2, float tolerance = 15f)
    {
      return Math.Abs(c1.GetHue() - c2.GetHue() <= tolerance;
    }
    

    For a more in-depth explanation of why this works, see this Wikipedia article on HSV colour spaces.

提交回复
热议问题