2012-04-12 11 views
2

Ich möchte in der Lage sein, die Hintergrundfarbe eines Winforms an einer bestimmten Stelle auf dem Bildschirm zu bestimmen, damit ich abhängig von dieser bestimmten Farbe etwas unternehmen kann. Leider scheint die System.Drawing-Bibliothek keine Methode anzugeben, die mir dies ermöglicht.Ermitteln der Farbe eines Pixels in einer Winforms-Anwendung

Wie soll ich dann die Farbe an einem bestimmten Punkt bestimmen?

+0

Mögliches Duplikat von http://stackoverflow.com/questions/1483928/how-to-read-the-color-of-a-screen-pixel – Marco

Antwort

5

verwenden, die:

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

namespace ColorUnderCursor 
{ 
    class CursorColor 
    { 
     [DllImport("gdi32")] 
     public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos); 

     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     public static extern bool GetCursorPos(out POINT pt); 

     [DllImport("User32.dll", CharSet = CharSet.Auto)] 
     public static extern IntPtr GetWindowDC(IntPtr hWnd); 

     /// <summary> 
     /// Gets the System.Drawing.Color from under the mouse cursor. 
     /// </summary> 
     /// <returns>The color value.</returns> 
     public static Color Get() 
     { 
      IntPtr dc = GetWindowDC(IntPtr.Zero); 

      POINT p; 
      GetCursorPos(out p); 

      long color = GetPixel(dc, p.X, p.Y); 
      Color cc = Color.FromArgb((int)color); 
      return Color.FromArgb(cc.B, cc.G, cc.R); 
     } 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct POINT 
    { 
     public int X; 
     public int Y; 
     public POINT(int x, int y) 
     { 
      X = x; 
      Y = y; 
     } 
    } 
} 
+0

Dies ist unvollständig, wo ist die 'DC' Variable definiert, die Sie verwenden GetPixel anrufen? – fuaaark

+0

Überprüfen Sie das Update ... –

+0

+1, Sie sind willkommen –

4

Angenommen, Sie möchten die Win32-API nicht verwenden, können Sie Graphics.CopyFromScreen() verwenden, um den Inhalt Ihres Bildschirms auf ein Bitmap-Objekt zu zeichnen. Von dort müssen Sie nur Bitmap.GetPixel() verwenden, um ein Color Objekt mit der richtigen Farbe abzurufen.

Hier einige Code, den Sie den kompletten Desktop verwenden können abgerufen werden (funktioniert mit mehreren Monitoren):

public Image GetScreenshot() 
{ 
    int screenWidth = Convert.ToInt32(System.Windows.SystemParameters.VirtualScreenWidth); 
    int screenHeight = Convert.ToInt32(SystemParameters.VirtualScreenHeight); 
    int screenLeft = Convert.ToInt32(SystemParameters.VirtualScreenLeft); 
    int screenTop = Convert.ToInt32(SystemParameters.VirtualScreenTop); 

    Image imgScreen = new Bitmap(screenWidth, screenHeight); 
    using (Bitmap bmp = new Bitmap(screenWidth, screenHeight, PixelFormat.Format32bppArgb)) 
    using (Graphics g = Graphics.FromImage(bmp)) 
    using (Graphics gr = Graphics.FromImage(imgScreen)) 
    { 
     g.CopyFromScreen(screenLeft, screenTop, 0, 0, new Size(screenWidth, screenHeight)); 
     gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
     gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
     gr.DrawImage(bmp, new Rectangle(0, 0, screenWidth, screenHeight)); 
    } 

    return imgScreen; 
} 
2

Dies ist eine etwas andere Perspektive auf der anderen Seite ist Antworten bereits angegeben, da Sie nur angegeben haben, dass Sie die "Farbe" bestimmen möchten, aber nicht explizit angegeben haben, dass Sie die RGB-Werte möchten.

Diese Unterscheidung ist notwendig, da es für eine Farbe Abweichungen geben kann, die für das menschliche Auge nicht wahrnehmbar sind. Nehmen wir zum Beispiel an, dass Sie daran interessiert sind, die Farbe "blau" zu erkennen. Die Werte (5, 5, 240) und (10, 10, 255) unterscheiden sich nur sehr geringfügig von (0, 0, 255). Tatsächlich ist der Unterschied so subtil, dass Sie die Farbfelder nebeneinander vergleichen müssten, um sie auseinander zu halten, und selbst dann hängt es von der Qualität Ihres Monitors ab. Sie sind auf meinem Desktop-Monitor subtil anders, aber auf meinem Laptop nicht zu unterscheiden. Um die lange Geschichte kurz zu machen, sind RGB-Werte eine schlechte Art, Farbe zu bestimmen.

Es gibt zahlreiche Methoden zur Berechnung des Unterschieds zwischen Farben, am häufigsten ist die Delta-E-Methode. Dies kann jedoch über tödlich sein, wenn Sie nur eine schnelle und schmutzige Methode wollen. Konvertieren Sie den RGB-Raum in HSV und verwenden Sie den Farbtonunterschied, um die Farbe zu bestimmen. Ändern Amen Beispiel, erhalten Sie die folgenden Schritte aus:

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(); 
     } 
    } 

Reines Blau hat einen Farbtonwert von 240. Die vorherigen Beispiele (5, 5, 240) und (10, 10, 255) sowohl einen Farbton von 240 haben. Dies ist eine gute Nachricht, da es bedeutet, dass der Farbton ein Maß ist, das gegenüber RGB-Abweichungen ziemlich tolerant ist, und der Unterschied ist auch schnell zu berechnen (dh, nehmen Sie einfach den absoluten Unterschied in den Farbtonwerten). An diesem Punkt sollten wir auch einen anderen Parameter einführen, der eine akzeptable Toleranz gegenüber Farbunterschieden regelt. Eine Toleranz von 15 Grad Farbton macht das System ziemlich robust.

Hier ist Beispielcode, der zwei Farben vergleicht, um zu bestimmen, ob sie in akzeptabler Weise ähnlich

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

Für eine tiefe gehende Erklärung, warum dies funktioniert, finden Sie in diese Wikipedia article auf HSV-Farbräumen.

Verwandte Themen