Picking Colors Out of a Picture with VC++.NET

Ever wonder how they make those nifty color pickers on graphics programs like Adobe Photoshop? Typically they have a formula that generates the colors of the spectrum and makes it into one of those colorful swatches. You may have the swatch but perhaps you want to know how you can go about giving your users the ability to mouse over the swatch and pick out colors. Maybe display things like the RGB value or possibly the hue, brightness and illumination of the color. Perhaps you have an image and want the user to have the ability to mouse over it and pick colors out of it. In either case we explore a way this can be done using our friend VC++.NET right here on the Programming Underground!

We can start our little project by creating a form with two pictureboxes and two labels on it. One picturebox will be loaded with a graphic of our swatch. You could be somewhat lame and just take a screenshot of Photoshop and cut it out of the screenshot… whatever works. As long as you have an image with all the colors you want in it you are good to go. This picturebox can be any size you choose but ideally should be the same size as the swatch image itself.

The second picturebox can be smaller and preferably square. This picturebox is going to show a solid color as we highlight over the swatch. Just like on your favorite graphics program for when you are choosing a foreground/background color. This second picturebox won’t actually contain a picture. We are just going to change its backcolor to reflect the color hovered over in pictureBox1. Knowing this, you could use whatever control you want to show the color.

To accompany these two pictureboxes we can add additional labels. Here we are going to add two labels to show the x and y position of the mouse within the swatch. We could also create three more labels to show the RGB values of the color or the hue/brightness/illumination of the color. I will leave that up to you. Once we have the color structure, it will just be a matter of populating your labels with the properties from that color structure.

So now we have all the players involved on a form and ready to go. You should have a picturebox loaded up with the swatch graphic, an empty picturebox and two empty labels for displaying coordinates.

The code below will show you how we can tie things together. We will start by first making sure to import the System::Drawing namespace into the project. This will give us access to the Image and Bitmap classes. Next we need to add some variables to our form. One will be “img” (to hold the image from our pictureBox1 control) and the other will be “bmp” which will hold the value of our new Bitmap object we create from the img variable. Lastly we will add two variables to hold the width and height of the Bitmap object.

// Set some variables in the form...
Image ^img;
Bitmap ^bmp;
int bitmapWidth;
int bitmapHeight;

We will set these variables to values in our Form_Load event. We will set the variable “img” to the Image from pictureBox1 and “bmp” will be a brand new Bitmap based on this image. We will also set the width and height variables to reflect the size of this new bitmap. We are going to do it here, instead of the mousemove event later, so that these don’t have to be fetched and calculated again and again during each move of the mouse. Since these values don’t change in our example, it is perfect to set them up in the form load.

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
	 // Get the image from our picturebox
	 img = pictureBox1->Image;

	 // Now make a bitmap out of it
	 bmp = gcnew Bitmap(img);

	 // Store the width and the height of this bitmap
	 // This will create our boundaries for getting pixels (shown below)
	 bitmapWidth = bmp->Width;
	 bitmapHeight = bmp->Height;			 
}

Ok, so we have the variables setup and set to their default values. Now we need to turn our attention to when the user moves their mouse over the image. This means we need a mousemove event on the pictureBox1 control. Each time the mouse moves over the image, it passes the event two arguments. The first is the pictureBox1 object itself (sender) and the other is the mouseEventArgs (e) which contains the information about the mouse’s state and position.

We will collect the mouse position, show the X and Y coordinates of the mouse in the labels for the user and then get the pixel in the image at that location. Once we have the location we can test to make sure that it is within the boundaries of our image (in case our picturebox is bigger than our swatch image we don’t want it throwing exceptions). If all is ok, we get the pixel using GetPixel() and give it the mouse coordinates. It will then return a Color object.

private: System::Void pictureBox1_MouseMove(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
	 // Get the mouse location in the image
	 int x = e->Location.X;
	 int y = e->Location.Y;

	 // Convert the coordinates to strings to store as visible values
	 String^ xstr = Convert::ToString(x);
	 String^ ystr = Convert::ToString(y);

	 label1->Text = xstr;
	 label2->Text = ystr;

	 // Get the pixel color at coordinates x, y
	 // But only if it fits within the boundaries of the image
	 if ((x < bitmapWidth) && (y < bitmapHeight)) {
		  // Get the color and set the background of our other picturebox to that color
		  Color colour = bmp->GetPixel(x,y);
		  pictureBox2->BackColor = colour;
	 }
}

So reading through it we get the coordinates of the mouse, convert them to strings for the labels, then compare the coordinates against the width and height of the bitmap we recorded earlier. If it is within the “boundaries” of the image, we go ahead and call the GetPixel() method of the bitmap object and store the color into a variable called “colour” (like the British spelling o’ chap?)

Once we have this color stored, we can do anything we want with it. Here we could use it to populate other labels for the RGB etc. Explore the properties of the Color structure and you will see properties “.R”, “.G”, “.B” to get the RGB values respectively.

However, we use it here to set the BackColor of our second picturebox and display the color to the user. That is it! We are all done!

Not too much code for a ton of functionality. I recommend putting all these controls together in a frame on a side bar somewhere or in a dialog screen and you can get very creative with color picking and color information. You could even move all this code to your own function, pass it the control you want to pick from, the mouse event object and refactor it into something a bit more generic that works with all kinds of controls. Makes for a great code library item.

How you enjoyed the code and feel free to rob me blind and use whatever you see here for your own purposes. As with all code on the Programming Underground it is completely in the public domain. Enjoy!

🙂

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebooks "The Programmers Idea Book" and "Diagnosing the Problem" . He has been a programmer for over 25 years. He works for a hot application development company in Vancouver Canada which service some of the biggest tech companies in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.