Get Image Colors

Image Information: For C# and VB NET Students

 

In the previous lesson, we added 256 labels to our Windows Form. We did this with code when the form loaded. In this lesson, we'll get the colors used in an image and then use those colors for the BackColor property of our labels.

We'll add the code to get an image's colors in our BtnLoad, right at the end. It looks like this so far (C#):

C# code showing how to get metadata from an image

And here's the code you should have if you're following along in VB Net:

Visual Baisc .Net code showing how to get metadata from an image

The comments in the image above are where you should add the new code. Let's make a start.

 

Image Color Palettes

Each image you open has a palette. The Palette property of an image has an array called Entries. You can use this array to get the colors used in your image. The Length property of Entries tells you the color count.

First, let's get that count of colors. Add this line in C#:

int colorPaletteLength = img.Palette.Entries.Length;

And this one in VB Net:

Dim colorPaletteLength As Integer = img.Palette.Entries.Length

So our image is stored in the img variable. We're then using img.Palette.Entries.Length to get a count of the colors. This is stored in the variable called colorPaletteLength.

The colors you get from the Entries array are not necessarily all different. There may be duplicates in there. The technique we'll use is to transfer the colors in Entries to another array. This will be a string array. We'll convert the Entries to a HTML color (hex value) and place this HTML value into the string array. It's this array that we'll do our duplicates check on.

So, add this array to your code:

C#:

string[] colorsArray = new string[colorPaletteLength]

VB Net

Dim colorsArray(colorPaletteLength) As String

Now we need to check if there is actually a color palette available and then check if the color count is between 0 and 256. If that's OK, we'll do our color stuff. Add this if statement in C#:

if (img.Palette != null && (colorPaletteLength > 0 && colorPaletteLength < 257))
{
}

And this one in VB Net:

If img.Palette IsNot Nothing And (colorPaletteLength > 0 And colorPaletteLength < 257) Then
End If

The rest of the code we'll write needs to be added inside of the if statement.

 

Convert Image Color to HTML

We'll loop round the colors in Entries, convert them to HTML, and then add them to our colorsArray. Add this loop body in C#:

for (int i = 0; i < colorPaletteLength; i++)
{
}

And this one in VB Net:

For i = 0 To colorPaletteLength - 1
Next

Inside the loop, we only need one line of code. It's a tricky line, though. Add this in C#:

colorsArray[i] = ColorTranslator.ToHtml(img.Palette.Entries[i]);

And this in VB Net:

colorsArray(i) = ColorTranslator.ToHtml(img.Palette.Entries(i))

There is a Class called ColorTranslator. Type a dot and you'll see a list. On the list is an item called ToHtml. In between the round brackets of ToHtml, you type the value you're trying to translate into a color. For us, this is an entry in img.Palette.Entries. (Entries is also an array, remember.)

 

Remove Duplicates in an Array

At this stage, we could write a Remove Duplicates function/method. We could use our array called colorsArray. After all, this is where the color hex values from the image are now stored. However, it's a lot easer to remove duplicates using a list, as there is a useful function/method called Contains. We can use this to check for duplicates.

It's a good idea to try and write your own remove duplicates routine, though. If you're ever going for an interview for a job as a programmer, this is a popular question that you may be asked. There is a good page on Stack Overflow with lots of routines and techniques you can study. The page is here:

Remove Duplicates Discussion

The technique we'll use is to set up a List. We can then check our string array, remove the duplicate and add it to the new list. This would not be a good technique to use if we had a very large array. But it's fine for an array that's going to have a maximum of 256 items.

Set up this List in C#:

List<string> removeDuplicateColors = new List<string>();

And this one in VB Net:

Dim removeDuplicateColors As New List(Of String)()

We'll use a For Each loop on our colorsArray. Add this foreach loop in C#:

foreach (var item in colorsArray)
{
}

And this For Each loop in VB Net:

For Each item In colorsArray
Next

The code to go inside of the loop is this in C#:

if (removeDuplicateColors.Contains(item) == false)
{

removeDuplicateColors.Add(item);

}

And this in VB Net:

If removeDuplicateColors.Contains(item) = False Then

removeDuplicateColors.Add(item)

End If

We're checking the new list to see if hold an item from them colors array. If it doesn't then we can go ahead and Add that item to the removeDuplicateColors list.

At the end of all that, we'll have a list with all the color values from our image. We can use these colors to set the BackColor property of our labels.

First, set up a counter:

C#:

int hexCount = 0;

VB Net

Dim hexCount As Integer = 0

Now add another For Each loop. This one in C#:

foreach (var hexVal in removeDuplicateColors)
{
}

And this one in VB Net:

For Each hexVal In removeDuplicateColors
Next

So we're looping round the removeDuplicateColors list now. We'll be getting a hex value. The hex value is one that we can use to color the label. We need to get the name of a label inside the loop. Add this code inside of your loop for C#:

ColorLabel("color" + hexCount.ToString(), hexVal);
hexCount++;

And this for VB:

ColorLabel("color" + hexCount.ToString(), hexVal)
hexCount += 1

You'll get underlined for ColorLabel as it's a routine we haven't written yet. But inside of the round brackets, we have this:

"color" + hexCount.ToString(), hexVal

The Sub/method we'll write will take two arguments, both string values. The first is the name of a label. We named our labels in the form Load event. They were like this:

color0
color1
color2
etc

 

Color the Labels on the Form

To construct the Name of a label we join together the word "color2" and the whatever is inside of hexCount. The variable hexCount is incremented each time round the loop. So this gets us all our label names. The second argument is the hex color itself, the one we need to color the label.

So, add this method in C#:

private void ColorLabel(string labelName, string labelColor)
{
}

And this Sub in VB Net:

Private Sub ColorLabel(labelName As String, labelColor As String)

End Sub

As the code for ColorLabel, we first need to find the name of a label on the form. Add this line to your method in C#:

var findLabel = Controls.Find(labelName, false).FirstOrDefault();

And this in VB Net:

Dim findLabel As Object = Controls.Find(labelName, False).FirstOrDefault()

That's a tricky line to understand. But, in VB, we're just creating a generic Object called findLabel. In C#, you can use the keyword var if you're not sure what type of variable it's going to be. After an equal sign, we have this:

Controls.Find(labelName, False).FirstOrDefault()

We want to Find a Control. Between the round brackets of Find, you first need what it is you're searching for, which is the name of a label in our case. After a comma, you say whether you want to search for all children. We don't because we only have one set of labels, so the value is False. After a dot, we have FirstOrDefault. This gets you the first item with the name you specified in the search, which was the name of a label for us.

We need to add an if statement next, just to make sure that a label with that name has been found. If so, we can color the label. Add this if statement in C#:

if (findLabel != null)
{
}

And this one in VB Net:

If findLabel IsNot Nothing Then
End If

Inside the if statement, we only need one line of code. This one in (delete the semicolon on the end in VB Net):

findLabel.BackColor = ColorTranslator.FromHtml(labelColor);

We're setting the BackColor property of our label, which is inside of findLabel. After the equal sign, we use the inbuilt ColorTranslator Class again. This time, instead of the ToHtml we used previously, we're using FromHtml. Inside the round brackets of FromHtml we have our labelColor, the hex value we passed over to our ColorLabel Sub/method.

And that it. Your ColorLabel method should look like this in C#:

A C# method to find a control on a form and color the background

And this in VB Net:

A VB Net method to find a control on a form and color the background

And the bottom of your BtnLoad code should be this in C#:

C# code that finds the colors in an image

And this in VB Net:

VB Net code that gets the colors in an image

Because this has been a tricky project, there's a text file with all the code in it.

C# Project Code

VB NET Project Code

Give it a try, though. Load up an image. Try a GIF first. You should see the colors in the image appear in your labels:

A Windows Form that gets all the colors used in the diaplyed image

And that's it for this project. It was a bit tough, but hope you got there!

Back to the C# NET Contents Page

Back to the VB NET Contents Page