Click here to Skip to main content
15,890,336 members
Articles / Programming Languages / C#
Article

Geting pixel color from screen shoot image

Rate me:
Please Sign up or sign in to vote.
4.79/5 (11 votes)
4 Jul 2008CPOL4 min read 57K   1.3K   30   4
Geting pixel color from screen shoot image
Image 1

Introduction

This article is suppose to show you a few simple techniques of image projection on pictureBox control, saving and loading images and a little bit of clipboard action. Take a peak at the code, you may find something useful. The idea of this program is simple, to take screen shoot, or any other image form file or clipboard, and catch the color of the pixel to clipboard with a single mouse click.

Background

So the other day at the college, my friend and I were enjoying the benefits of wireless network and mainly looking for cool pictures we could use for our CSS homework. So very often you find a good picture, but to get some colors so you can integrate it to your web page, you need some of the tools to get the HEX. This tools are memory consuming, too professional and just not suitable for this simple use. So, we said, hmm.. Let's find some simple tool just to get the HEX color code of selected pixel.. or better yet, let's make our one, and here it is. Let's check it out...

Using the code

So what do we do first? - It is useful to have a pictureBox in witch we shall display our image, and also a function to load image to pictureBox form external file. So here is the code for loading the image into pictureBox:

C#
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Load image from file...";
ofd.Filter = "JPEG image|*.jpg|Bitmap|*.bmp";
if (ofd.ShowDialog() == DialogResult.OK)
{
    globals.image = new Bitmap(ofd.FileName);
    pictureBox1.Image = globals.image;
}

Note that in my application you can move image around the pictureBox, well actually that's a trick. You need to place the pictureBox control into panel control. Now you set the pictureBox property SizeMode to AutoSize, and voila if the image is bigger then the panel control, it will display scroll bars. Note that I can also drag it with mouse.

Clearly I used the MouseMove method, and here it is:

C#
try
{
    if (pictureBox1.Image != null && globals.image.Width > e.X && globals.image.Height > e.Y)
    {
        //drag the image
        if (e.Button == MouseButtons.Left)
        {
            int maxWidth = -(globals.image.Width - panel1.Width) - 17;
            int maxHight = -(globals.image.Height - panel1.Height) - 17;
            if ((pictureBox1.Left + e.X - globals.x) <= 0 && (pictureBox1.Left + e.X - globals.x) >= maxWidth)
                pictureBox1.Left += e.X - globals.x;
            if ((pictureBox1.Top + e.Y - globals.y) <= 0 && (pictureBox1.Top + e.Y - globals.y) >= maxHight)
                pictureBox1.Top += e.Y - globals.y;
        }

        Color color = globals.image.GetPixel(e.X, e.Y);
        panel2.BackColor = color ;
        toolStripStatusLabel1.Text = "RGB: " + color.R.ToString() + "," + color.G.ToString() + "," + color.G.ToString();
        toolStripStatusLabel2.Text = "#" + color.R.ToString("x").ToUpper() + color.G.ToString("x").ToUpper() + color.B.ToString("x").ToUpper();
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

In the MouseDown method, I save coordinates. Now when user is "dragging" the pictureBox, you calculate the distance between clicked location and move the image. Try to play with this code snippet you will soon figure it out. Next thing to do on MouseMove event is to get pixel color, and display it on some label. Note the ToString("x"), this is used to convert to HEX.

Wouldn't it be cool if you take a screen shoot using print screen key, and when the application starts that it automatically shows it? Sure, and here is the way to do it:

C#
globals.image = (Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap);
pictureBox1.Image = globals.image;
toolStripStatusLabel1.Text = "";
toolStripStatusLabel2.Text = "";

Using this code you capture an object form clipboard, and if it's an image it saves it to variable image stored in class globals. Also here is the code to populate pictureBox, and reset label text.

Next thing to do is saving an image to file, and also capturing that HEX color value from a selected pixel. One way to save an image is using file stream, and different image formats:

C#
SaveFileDialog sfd = new SaveFileDialog();
sfd.Title = "Save screen shoot as...";
sfd.Filter = "JPEG Image|*.jpg|Bitmap|*.bmp|PNG Image|*.png";
sfd.ShowDialog();
if (sfd.FileName != "")
{
    FileStream fs = (FileStream)sfd.OpenFile();
    switch (sfd.FilterIndex)
    {
        case 1:
            globals.image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg);
        break;
        case 2:
            globals.image.Save(fs, System.Drawing.Imaging.ImageFormat.Bmp);
        break;
        case 3:
            globals.image.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
        break;
    }
    fs.Close();
}

To save some text to clipboard, in our case the HEX color code, all you need to to is this:

C#
Clipboard.SetText(toolStripStatusLabel2.Text);

One of the main reasons for creation of this application is simplicity and quick work. So I've also implemented a way to take a screen shoot. Now you are only one click away, and before that you needed to press two keyboard keys.
First of all you create a graphic on the current form, and get the user screen size. Next, you create new instance of Bitmap class, or in simple language an image witch is the same size as the user screen size (resolution). The second graphics object is created so later you can draw image into the image variable. Sure, you don't want your application to get in the way of your screen shooting, so you need to hide it, and when the screen is copied into the screen graphics you display it again. When testing this application I've noticed when taking screen shoot of desktop, not all icons were in the image, so I put this thread to sleep for 100 milliseconds so that all the systems refreshing and object drawing doesn't get in the way.

C#
Graphics g = this.CreateGraphics();
Size s = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Size;

globals.image = new Bitmap(s.Width, s.Height, g);
Graphics screen = Graphics.FromImage(globals.image);

this.Hide();
System.Threading.Thread.Sleep(100); // so the screen shoot is complete
screen.CopyFromScreen(0, 0, 0, 0, s);

this.Show();

screen.DrawImage(globals.image, 0, 0);
pictureBox1.Image = globals.image;
g.Dispose();

I think that's about it. There are a few lines of code that I didn't describe, like enabling and disabling of some selections, or the resize settings. In short, you can't save an image if the picture box is empty, so you disable it. You may see that when the form is resized it keeps it's original position, for this you can use anchors. Usually I've used the code until I discovered it.

Points of Interest

So here it is. Use it well, and I hope you'll make some use of it.. Enjoy, cheers!

Updates

04.07.2008 - new version uploaded, convolution filter added

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Croatia Croatia
Ivan Svogor, is a final year graduate student of Information and Software Engineering at university of Zagreb, Croatia. His interests is SOA, human computer interaction, computer & embedded systems (sensors) integration, basically he likes cool stuff Smile | :) ...

Comments and Discussions

 
QuestionThanks! Pin
Member 1254020926-Aug-16 16:27
Member 1254020926-Aug-16 16:27 
GeneralThanks Pin
carmi21-Jan-09 21:29
carmi21-Jan-09 21:29 
QuestionSuggestion... Pin
StephB4-Jul-08 3:03
StephB4-Jul-08 3:03 
AnswerRe: Suggestion... Pin
Ivan Svogor4-Jul-08 3:30
Ivan Svogor4-Jul-08 3:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.