Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / WPF
Tip/Trick

Strings To Colours

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
17 Jun 2014CPOL1 min read 5.5K   6  
A String To Brush Converter for WPF/Silverlight

Introduction

I was creating an application that was displaying on a graph a number of different items, and I wanted to visually differentiate these items by their text.

Background

If you've not used XAML Converters before then in simple terms, they are class that implements the IValueConverter interface.  This interface has two methods Convert and ConvertBack.  The methods take an object of one type and convert it to another.  This class can then be added as a resource to your XAML markup and used in any binding.

See this MSDN article for more information.

Using the code

The class is straight forward and looks like:

C#
    using System;
    using System.Security.Cryptography;
    using System.Text;
    using System.Windows.Data;
    using System.Windows.Media;
    
    public class StringToBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType
            , object parameter, System.Globalization.CultureInfo culture)
        {
            if (value != null && value is string)
            {
                string text = (string) value;
                byte[] data;

                //create a 16 byte md5 hash of the string
                using (MD5 md5 = MD5.Create())
                    data = md5.ComputeHash(Encoding.UTF8.GetBytes(text));

                //use 3 values from the hash to create the colour
                //provide an alpha value to prevent readability issues
                //if this colour is used as a text background
                return new SolidColorBrush(
                    Color.FromArgb(180, data[0], data[7], data[15]));
            }
            return new SolidColorBrush(Color.FromRgb(255, 255, 255));
        }

        public object ConvertBack(object value, Type targetType
            , object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

After some checks that your passed object is a string, we calculate a MD5 hash of the string and pick 3 random values from that hash (the data[0], data[7] and data[15]) to create a new brush.

If you're asking why? That's reasonable, this wasn't my first solution, I started with what probably everyone would start with, converting the string to their ASCII codes.  And yes this works, but there's a fairly massive issue...consider strings that almost the same (e.g. DataItem5, DataItem16) with the ASCII method you'll end up with colours that are pretty much indistinguishable. The reason is for most text your using around 90 values and you're mapping that to a pool of 2,147,483,947 possible colours. 

If you want to use this approach in a Windows Forms or ASP or anywhere else, then you only need the code within the if block, and then just return the Color rather than the XAML SolidColorBrush object.

Points of Interest

Is there a less computationally expensive method of achieving the same thing?

Could you ever implement the ConvertBack method? :D

History

1st and hopefully only version:)

License

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


Written By
Software Developer Bank Of Ireland
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --