.
GDI+ FAQ
Skip Navigation LinksWelcome : GDI+ FAQ : Finding the colour at a certain point. (eyedropper)

Creating an image "eyedropper"

Under Win32 the process of capturing the colour of a pixel was relatively simple. The screen DC had a bitmap selected into it, the display memory itself, and it was possible to simply get the pixel at the desired position with a few lines of code.

GDI+ makes this process a little more complex because the GDI+ device context works in a slightly different way and provides no GetPixel or SetPixel functionality. This means that to obtain the colour of an arbitrary point we need to resort to a little bit of interop.

To obtain the correct Win32 functions to call, the DllImport attribute is used. In this example we'll be importing the GetPixel function from GDI32.DLL and the GetDC and ReleaseDC methods from User32.DLL.

Once the functions are imported the GDI DC of any window or the desktop can be used to call the GetPixel method and the resulting colour obtained using the ColorTranslator class.

So that any pixel on screen can be obtained, the application uses a timer to fire 10 times a second. When the timer fires the Control.MousePosition property is used to obtain the position of the mouse in screen-coordinates. To display the colour obtained, a panel background is set each time the colour is sampled.

The listing shown below details the process. Choose C# or VB code using the buttons at the top of this page.

using System;

using System.Runtime.InteropServices;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

 

namespace pixelcolor

{

  /// <summary>

  /// Summary description for Form1.

  /// </summary>

  public class Form1 : System.Windows.Forms.Form

  {

 

 

    [DllImport("Gdi32.dll")]

    public static extern int GetPixel(

    System.IntPtr hdc,    // handle to DC

    int nXPos,  // x-coordinate of pixel

    int nYPos   // y-coordinate of pixel

    );

 

    [DllImport("User32.dll")]

    public static extern IntPtr GetDC(IntPtr wnd);

 

    [DllImport("User32.dll")]

    public static extern void ReleaseDC(IntPtr dc);

 

 

    private System.Windows.Forms.Panel panel1;

    private System.Timers.Timer timer1;

 

    /// <summary>

    /// Required designer variable.

    /// </summary>

    private System.ComponentModel.Container components = null;

 

    public Form1()

    {

      //

      // Required for Windows Form Designer support

      //

      InitializeComponent();

      this.SetStyle(ControlStyles.ResizeRedraw,true);

    }

 

    /// <summary>

    /// Clean up any resources being used.

    /// </summary>

    protected override void Dispose( bool disposing )

    {

      if( disposing )

      {

        if (components != null)

        {

          components.Dispose();

        }

      }

      base.Dispose( disposing );

    }

 

    #region Windows Form Designer generated code

    /// <summary>

    /// Required method for Designer support - do not modify

    /// the contents of this method with the code editor.

    /// </summary>

    private void InitializeComponent()

    {

      this.panel1 = new System.Windows.Forms.Panel();

      this.timer1 = new System.Timers.Timer();

      ((System.ComponentModel.ISupportInitialize)(this.timer1)).BeginInit();

      this.SuspendLayout();

      //

      // panel1

      //

      this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;

      this.panel1.Location = new System.Drawing.Point(216, 8);

      this.panel1.Name = "panel1";

      this.panel1.Size = new System.Drawing.Size(64, 56);

      this.panel1.TabIndex = 0;

      //

      // timer1

      //

      this.timer1.Enabled = true;

      this.timer1.SynchronizingObject = this;

      this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);

      //

      // Form1

      //

      this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

      this.BackColor = System.Drawing.Color.White;

      this.ClientSize = new System.Drawing.Size(292, 273);

      this.Controls.Add(this.panel1);

      this.Name = "Form1";

      this.Text = "Form1";

      this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);

      ((System.ComponentModel.ISupportInitialize)(this.timer1)).EndInit();

      this.ResumeLayout(false);

 

    }

    #endregion

 

    /// <summary>

    /// The main entry point for the application.

    /// </summary>

    [STAThread]

    static void Main()

    {

      Application.Run(new Form1());

    }

 

    private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)

    {

      Random r=new Random(1);

 

      for(int x=0;x<100;x++)

      {

        SolidBrush b=new SolidBrush(Color.FromArgb(r.Next(255),r.Next(255),r.Next(255)));

        e.Graphics.FillRectangle(b,r.Next(this.ClientSize.Width),r.Next(this.ClientSize.Height),r.Next(100),r.Next(100));

      }

    }

 

    private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

    {

      Point p=Control.MousePosition;

      IntPtr dc=GetDC(IntPtr.Zero);

      this.panel1.BackColor=ColorTranslator.FromWin32(GetPixel(dc,p.X,p.Y));

      ReleaseDC(dc);

    }

  }

}

 

If you wanted to sample the colours in a PictureBox or in your own form then you simply need to obtain the DC for that object. This can be accomplished using CreateGraphics, Graphics.GetHdc and Graphics.ReleaseHdc. The listing below shows a MouseMove handler that can be used to obtain the pixel colour from a form.

    protected override void OnMouseMove(MouseEventArgs e)

    {

      Graphics g=this.CreateGraphics();

      IntPtr myDC=g.GetHdc();

      Color c=ColorTranslator.FromWin32(GetPixel(myDC,e.X,e.Y));

      g.ReleaseHdc(myDC);

 

      this.panel1.BackColor=c;

    }

 

Return to the GDI+ FAQ

Visit Windows Forms Tips and Tricks

Copyright � Bob Powell 2004-2005 All Rights Reserved.

 

Sponsored By
DaraizeTechnologies.com

&
Proteus Groupe

Bob Powell

Create your badge

Copyright © Bob Powell 2000-2012.  All rights reserved.