Dan Rigsby - Coding Up Style

Developer.Speaker.Blogger

Archive for the '.Net' Category


New Webcast: Syndication in .Net

Posted by Dan Rigsby on 7th November 2008

screencast1thumb-thumb I have a new 6 min 23 sec training webcast up over Syndication in WCF.  This video shows you how to use the System.ServiceModel.Syndication namespace to create and consume RSS or Atom feeds. It builds on top of the Understanding REST video, but understanding of REST is not necessary. This video also complements a recent presentation I have been giving called “RESTing on the Web with WCF” which includes a segment on working with syndications.

So what are you waiting for?  Head on over and check out the webcast!

The video available through JupiterMedia and can be viewed at http://www.internet.com/video/. Just look for the "Developer Video" titled "Syndication in .Net".

Direct links are:
http://link.brightcove.com/services/link/bcpid1431564240/bclid1433966034/bctid1900229538

DotNetKicks Image

Posted in .Net, Webcast | 1 Comment »

New Webcast: Date & Times in .Net 3.5

Posted by Dan Rigsby on 27th August 2008

screencast I have a new 9 min 0 sec training webcast out over the new DateTimeInfo and TimeZoneInfo structs in .Net 3.5.  This video complements two of my recent blog posts:

  1. TimeZone vs. TimeZoneInfo in .Net
  2. DateTime vs. DateTimeOffset in .Net

It is available through JupiterMedia and can be viewed at http://www.internet.com/video/. Just look for the "Developer Video" titled "Date & Times in .Net 3.5".  Direct links are:

http://www.internet.com/video/?bcpid=1431564240&bclid=1433966034&bctid=1757572900
http://link.brightcove.com/services/link/bcpid1431564240/bclid1433966034/bctid1757572900

Posted in .Net, Webcast | 1 Comment »

TimeZone vs. TimeZoneInfo in .Net

Posted by Dan Rigsby on 24th August 2008

Working with Dates and Times in .Net 3.5 Series:
Part 1: DateTime vs. DateTimeOffset in .Net
Part 2: TimeZone vs. TimeZoneInfo in .Net

This is Part 2 in a series on working with Dates and Times in .Net 3.5.  You might want to read Part 1: DateTime vs. DateTimeOffset in .Net in WCF before continuing on with this post.

MoonKnt_12The TimeZone data type was introduced in .Net 1.0 as a mechanism for retrieving information about the current time zone, and to convert times from local time to Coordinated Universal Time (UTC) or vice versa.  The down side is that you cannot use this to represent any other time zone other than the local zone.  It also can’t be used to convert one date time to another zone.  This is a pretty sever limitation and something that .Net has been lacking for some time.

In .Net 3.5, Microsoft finally introduced a replacement for TimeZone.  The TimeZoneInfo class fills in all of the gaps where TimeZone left off.  You can represent any time zone and perform various calculations.  Many people have yet to hear of this class, but it is crucial if you are working with applications that need to perform calculations on dates and times which may originate from differet time zones. The major functions of this class include the ability to:

  • Retrieving a time zone that is already defined by the operating system. This can be retrieved by ID or the current local time zone.
  • Converting times between different time zones.
  • Enumerating the time zones that are available on a system.
  • Find all time zones a DateTime or DateTimeOffset can represent.
  • Creating a new time zone that is not already defined by the operating system.
  • Serializing a time zone for later retrieval.

View the complete list of members here: http://msdn.microsoft.com/en-us/library/system.timezoneinfo_members.aspx

Use this class to work with any time zone that is predefined on a system, to create new time zones, and to easily convert dates and times from one time zone to another. The TimeZoneInfo class replaces the TimeZone class in every way.  For all new development, ignore the TimeZone class and move straight to TimeZoneInfo.  The TimeZone class should probably have been marked as “Obsolete”.

How TimeZone class works

TimeZone timeZone = System.TimeZone.CurrentTimeZone;
Console.WriteLine(timeZone.StandardName);
 
With the TimeZone class you could pull the current time zone with the static CurrentTimeZone static property.  The TimeZone class has no constructors and fairly limited use.  You can convert dates and times from the local zone to UTC, but you have no access to other time zones.

How to retrieve a time zone with TimeZoneInfo

TimeZoneInfo hwZone =
    TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time");
TimeZoneInfo info = TimeZoneInfo.Local;
 
The TimeZoneInfo class allows you to access the local time zone with the Local static property.  This is similar to the TimeZone class.  However, TimeZoneInfo also allows you to reference any time zone with the FindSystemTimeZoneById static method. This method takes in a string which represents the Id for the time zone. Once you have this time zone, you can work with methods on the object to perform a variety of conversions.
 
A TimeZoneNotFoundException is thrown if the time zone ID could not be found on the local system.

How to convert times between different time zones with TimeZoneInfo

The TimeZoneInfo provides a few conversion methods to allow conversions between different time zones.  The most useful of which is the ConvertTime method.  With this, you can pass in a date/time and the time zone in which you want to convert it into.  If you are using DateTimeOffset, then when you compare the two date/time values, they are equivalent since they both represent the same time, just in different time zones.

DateTimeOffset nowDateTime = DateTimeOffset.Now;
DateTimeOffset newDateTime = TimeZoneInfo.ConvertTime(
    nowDateTime,
    TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time"));
Console.WriteLine("Now: {0}", nowDateTime);
Console.WriteLine("Now in Hawaii: {0}", newDateTime);
 
timezoneinfo1 

How to enumerate through all time zones on the computer with TimeZoneInfo

The GetSystemTimeZones method of the TimeZoneInfo class returns a ReadOnlyCollection of all of the time zones that the current system knows about.

ReadOnlyCollection<TimeZoneInfo> timeZones = TimeZoneInfo.GetSystemTimeZones();
Console.WriteLine("All time zones:");
foreach (TimeZoneInfo timeZoneInfo in timeZones)
{
    Console.WriteLine("   {0}", timeZoneInfo.DisplayName);
}

timezoneinfo2 

How to find all time zones a DateTime or DateTimeOffset can represent with TimeZoneInfome

Most date time offset can represent multiple time zones.  For instance, if a date and time have a –6 hour offset, this could be in the Central Time, Central American, Saskatchewan, or Guadalajara.  With the TimeZoneInfo class, you can easily find all of the time zones that the date and time could represent by simply interating over all of the time zones on the system and comparing their offset to the offset stored in the DateTimeOffset object:

DateTimeOffset current = DateTimeOffset.Now;
ReadOnlyCollection<TimeZoneInfo> timeZones = TimeZoneInfo.GetSystemTimeZones();
Console.WriteLine("You might be in the following time zones:");
foreach (TimeZoneInfo timeZoneInfo in timeZones)
{
    // Compare offset with offset for that date in that time zone
    if (timeZoneInfo.GetUtcOffset(current).Equals(current.Offset))
    {
        Console.WriteLine("   {0}", timeZoneInfo.DisplayName);
    }
}
 
This code outputs all of the following time zones.  DateTimeOffset.Now happens to represent “Eastern Time” in this example.
 
timezoneinfo3 

How to create a new time zone with TimeZoneInfo

The TimeZoneInfo class has no constructors, so it is impossible to new up a new instance.  However, it does provide a static method called CreateCustomTimeZone that allows you to create a new time zone to work with.  This method has a couple of overrides to provide you with everything needed to create a new time zone.  The following creates a new simple time zone called “My Custom Time Zone” which has a –4 hour offset from GMT and observes daylight savings time.

TimeZoneInfo info = TimeZoneInfo.CreateCustomTimeZone(
    "My Custom Time Zone",
    new TimeSpan(-4, 0, 0),
    "My Custom Time Zone",
    "My Custom Time Zone",
    "My Custom Time Zone",
    new TimeZoneInfo.AdjustmentRule[] { },
    false);

How to serialize a time zone with TimeZoneInfo

One of the unique features of the TimeZoneInfo class is that it has a native method to serialize the time zone to a string.  The ToSerializedString method is unlike other serialization methods in that it doesn’t serialize to xml by default, but instead to a semicolon delimited list.  This serialized string can be stored to disk or some other location for later retrieval.

TimeZoneInfo info = TimeZoneInfo.Local;
string serialized = info.ToSerializedString();
 
This code produces the following output:

Eastern Standard Time;-300;(GMT-05:00) Eastern Time (US & Canada);Eastern Standard Time;Eastern Daylight Time;[01:01:0001;12:31:2006;60;[0;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2007;12:31:9999;60;[0;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];

To deserialize the string back into a TimeZoneInfo class, you can use the FromSerializedString static method to create a new TimeZoneInfo object.

TimeZoneInfo info2 = TimeZoneInfo.FromSerializedString(serialized);
DotNetKicks Image

Posted in .Net, C# | 10 Comments »

DateTime vs. DateTimeOffset in .Net

Posted by Dan Rigsby on 23rd August 2008

Working with Dates and Times in .Net 3.5 Series:
Part 1: DateTime vs. DateTimeOffset in .Net
Part 2: TimeZone vs. TimeZoneInfo in .Net

MoonKnt_12 The DateTime data type has been around since .Net 1.0 and suited us well for a long time.  It simply defines a date and a time together and offers methods for working with these constructs. It is a struct and hence can’t be set to null.  This caused some people some problems over the years.  Especially when modeling a DateTime from the database, since in most databases like SQL Server, the datetime field can be null.  So, usually a null DateTime would be set to DateTime.MinValue.  However, this wasn’t the most optimal solution.

In .Net 2.0 nullable types were introduced.  Now, we could have a null DateTime by simply defining the field as  System.Nullable<DateTime> (or DateTime?) instead of the standard DateTime.  This allowed us to set the field to null, and pull the value using the Value property of the field.

In .Net 3.5 an entirely new date/time field was added called DateTimeOffset.  This data extends the DateTime to add in the concept of a timezone offset.  It is still a struct, so you need to use System.Nullable<DateTimeOffest> if you want to be able to have a null value. A DateTimeOffset value is not tied to a particular time zone, but can originate from any of a variety of time zones.  For example, there are can multiple timezones that represent the same offset such as UTC –6:00 which can be Central Time, Central American, Saskatchewan, or Guadalajara.  So you don’t know the timezone that the datetime represents, but you do know the offset.  This is all you need to perform comparisons to other DateTimeOffsets.

180px-PrimemeridianThe offset value represents the time difference between the current time and Greenwich Mean Time (GMT) this is known as Coordinated Universal Time (UTC).  GMT historically is the time when the sun crosses the Prime Meridian line which is located a 0 Longitude. IT is measured from the Greenwich Meridian Line at the Royal Observatory in Greenwich, England.  This is the place from where all time zones are measured. Even the atomic clocks of the world are adjusted by leap seconds to maintain synchronicity with GMT.

So why is UTC so important to software developers?  This may be an obvious answer to most, but if you haven’t been exposed to this, it’s because many applications need to be globalized and may be run in different timezones.  If someone enters in a date and time, is that relative to their timezone or the timezone the server is sitting on.  This can be vastly different and can really cause problems in your application.  Comparing all dates and times to the relative time of GMT allows applications to understand what the date and time actually represent.

What does DateTime and DateTimeOffest look like

Console.WriteLine(DateTime.Now);
Console.WriteLine(DateTimeOffset.Now);
 
datetime1
 
This print out shows the basic difference in the two types.  The DateTime shows the Date and Time, while the DateTimeOffset shows the Date, Time, and offset.  This offset represents the difference from GMT.  In this case 4 hours behind GMT.

How to convert from DateTime to DateTimeOffset

DateTime d1 = DateTime.Now;
DateTimeOffset o1 = new DateTimeOffset(d1);
DateTimeOffset of1 = new DateTimeOffset(d1, new TimeSpan(-5, 0, 0));
 
To convert a DateTime into a DateTimeOffset, you just need to pass the DateTime value into one of the constructors of the DateTimeOffset.  You could just pass the DateTime in (as in o1 above), or you can also pass in the DateTime and an offset (as in of1 above).  If you don’t supply an offset, then GMT is assumed.

How to convert from DateTimeOffest to DateTime

DateTimeOffset o2 = DateTimeOffset.Now;
DateTime d2 = o2.DateTime;
 
Converting a DateTimeOffset to a DateTime is easy.  Since the DateTimeOffset value contains all of the data of a DateTime field and more, there is a simple DateTime property on the DateTimeOffset struct that returns a DateTime representation of the value.

How to manually set DateTime and DateTimeOffset

DateTime dt1 = new DateTime(2008, 8, 22, 1, 0, 0);
DateTimeOffset do1 = new DateTimeOffset(2008, 8, 22, 1, 0, 0, new TimeSpan(-5, 0, 0));
Console.WriteLine(dt1);
Console.WriteLine(do1);
 
datetime2 
 
Manually setting a DateTimeOffset is very similar to setting the value of a DateTime.  The only difference is that you can also pass in a TimeSpan as the last argument that represents the GMT offset.

Arithmetic with Datetime and DateTimeOffest

DateTime dateTime1 = DateTime.Now;
DateTime dateTime2 = DateTime.UtcNow;
Console.WriteLine("{0} - {1} =", dateTime1, dateTime2);
Console.WriteLine(dateTime1 - dateTime2);

Console.WriteLine();

DateTimeOffset offset1 = DateTimeOffset.Now;
DateTimeOffset offset2 = DateTimeOffset.UtcNow;
Console.WriteLine("{0} - {1} =", offset1, offset2);
Console.WriteLine(offset1 - offset2);
 

datetime3

With this example we can see that the difference between Now and UtcNow is 0.  This means that the DateTimeOffset sees the UTC version of the time and the local version of the time as equal.  But what about something more complicated? Are 12 PM EST and 9AM PST equal?

DateTimeOffset ao1 = new DateTimeOffset(2008, 8, 22, 12, 0, 0, new TimeSpan(-5, 0, 0));
DateTimeOffset ao2 = new DateTimeOffset(2008, 8, 22, 9, 0, 0, new TimeSpan(-8, 0, 0));
Console.WriteLine(ao1 == ao2);
 
This code creates 2 times.  One is 12 PM August, 22 2008 and the second is 9 AM August, 22 2008.  However, the offsets for each are set for Eastern Standard time and Pacific Standard time respectively.  If we compare these two values, are they equal?  If you guessed “Yes”, then you are right.  The Equals() method of DateTimeOffset knows now to compare against the offsets.  This is incredibly useful when comparing times cared in different time zones.

When to use DateTime or DateTimeOffest

Use DateTimeOffest structure to work with dates and times whose offset (or difference) from UTC is known or when calculations need to be performed on dates that may be from different timezones. The DateTimeOffset value is also more portable from one computer to another than a DateTime value.  DateTimeOffset doesn’t necessarily replace DateTime though.  DateTime is still useful to represent a single date or time or when the timezone information is unknown or not important.  However most developers should explore using DateTimeOffest more in general use especially in enterprise level systems.

DateTime may also be the best type to represent a DateTime from the database since the DateTime fields in most databases don’t store timezone information.  In SQL Server 2008 a DateTimeOffset structure was introduced to the database as well.  This type is very comparable to the DateTimeOffset field in .Net.  So a good rule of thumb may be to use the corresponding types when mapping between SQL Server 2008 and .Net 3.5.

 

Update: Nicholas Allen posted a reminder of how to deal with DateTimeOffest fields when working with svcutil.exe: http://blogs.msdn.com/drnick/archive/2008/09/04/getting-better-time-formats.aspx

DotNetKicks Image

Posted in .Net, C# | 8 Comments »

Visual Studio 2008 SP1 and .Net Framework 3.5 SP1 now Officially RTM

Posted by Dan Rigsby on 11th August 2008

We knew it would be released soon since SQL Server 2008 went RTM with .Net Framework 3.5 SP1.  Visual Studio 2008 SP1 is now RTM and available for download off the MSDN subscriber’s web site:

VS2008SP1

They are available for general download here:

Get downloading!  The servers are busy at the moment, but this is worth the wait.

Posted in .Net, Visual Studio | 1 Comment »

.Net Framework 3.5 and Visual Studio 2008 SP1 very close to release

Posted by Dan Rigsby on 7th August 2008

  When installing SQL Server 2008 RTM, it failed with the following error:

MSSQLSP1

The SQL Server 2008 install installed a new version of .Net Framework 3.5 SP1, but if you have Visual Studio installed, you must upgrade to SP1 which isn’t officially released yet.  This does appear to be the final version of the .Net Framework 3.5 SP1 since it is shipping with SQL Server 2008 RTM.  Expect an official release within days along with Visual Studio 2008 SP1!

VSAbout

Posted in .Net, Visual Studio | 2 Comments »

JavaScriptSerializer Undeprecated in .NET 3.5 SP1

Posted by Dan Rigsby on 28th May 2008

According to Scott Guthrie (see comments in this post) it appears that the JavaScriptSerializer will be undeprecated in .NET 3.5 SP1.  In was deprecated in .Net 3.5 and the DataContractJsonSerializer replaced it.  Each of these serializers serializes to Json and each have their pluses and minuses:

  • JavaScriptSerializer supports anonymous types.
  • JavaScriptSerializer works with plain strings so it can be easier to use.
  • DataContractJsonSerializer can serialize DateTimes into UTC format.   Very important over the web!

I guess the big question I have is, do we really need both? Isn’t there a way to combine these into one serializer?

What about the act of undeprecating a class?  Do you think this is a good thing?

See these links for more information about the DataContractJsonSerializer:

Posted in .Net | 3 Comments »

Sexagesimal Conversions in .Net

Posted by Dan Rigsby on 30th April 2008

No, that is not a dirty word, and yes, it is fun to say. [sek-suh-jes-uh-muhl]

7520012074151Sexagesimal is a base-60 number system much like our own base-10 decimal system.  Throughout history different cultures have chosen different base numbering systems based on things they considered common or sacred.  Many people today recognize numbers as always being base-10, and it can be quite difficult to explain a different numbering system to a child.  Those of us in computer science are quite use to a base-2 (binary) system.  Some of the more common historic number systems are:

  1. Base-5 (quinary): This system has been popular because five can easily be represented by the five fingers on one hand
  2. Base-8 (octal): Some cultures used only their fingers to count and used the thumbs as place holders.  While other cultures, such as the Yuki Native American tribe of Northern California , counted the spaces between the fingers.  The Yuki actually started counting with 0 as well (much like C based languages).  So the numbers 0-7 were counted on their fingers.
  3. Base-10 (decimal): We are all familiar with the base-10 system which is almost universally used around the world.  Historical this is based on the fact that humans have ten fingers on which to count.
  4. Base-12 (duodecimal):  This system is based on the knuckles of the four fingers.  Each finger has 3 knuckles and the thumb is used as the place holder.  Twelve is also an important unit in British measurement such as 12 inches in a foot, 12 pennies to a shilling, 12 numbers used in our time units, etc.
  5. Base-20 (vigesimal): The base-20 system originates from the combination of ten fingers and ten toes on which to count.  This is most widely known to be used by the Mayan civilization.
  6. Base-60 (sexigesimal): The base-60 system dates back to the Sumerians and the early cultures of Mesopotamia.  It’s hard to say where this system originated from, but common belief is that it is a combination of the base-10 and base-12 systems.

So why is the base-60 system still important to us today?  Well for one, there are 60 seconds in a minute and 60 minutes in an hour.  This measurement one of the Sumerian’s lasting impressions today.  Their calendar and type systems have been adopted and modified throughout the Asia and Europe.  We can blame the Sumerian’s for not having enough time in the day.

180px-Geographic_coordinates_sphere.svg Another popular use for the base-60 system is in angular measure in our spherical coordinate system of the Earth.  A degree is divided into 60 minutes and a minute is divided into 60 seconds.  Our system of Latitudes and Longitudes is expressed in these terms.  With the popularity of geo-spatial and mapping tools such as Google Maps and Microsoft Live Maps, it has become important to be able to convert from degrees/minutes/seconds into a decimal notation and vice versa.

Example:

(49°30′02"N, 123°30′30")

 

49 degrees, 30 minutes, and 2 seconds by 123 degrees, 30 minutes, and 30 seconds

Below is a utilities class that I originally wrote for an astronomical observatory simulation application called StellarResults (which is available on codeplex).  This program would simulate observatories around the world and what astronomical objects they could see at a give time of day.  I soon realized that I needed to push this library down to a more basic level so that I could use it for other geo-spatial calculations such as working with geo-coded locations, or entering locations into a database.  Libraries like this will also be useful when working with the new spatial database features in Microsoft SQL Server 2008.

public static class GISUtilities
{
    #region Sexagesimal
    /// <summary>
    /// Converts from degrees, minues, seconds to a double.
    /// </summary>
    /// <param name="degrees">The degrees.</param>
    /// <param name="minutes">The minutes.</param>
    /// <param name="seconds">The seconds.</param>
    /// <returns></returns>
    public static double ConvertSexagesimalToDouble(
        int degrees,
        int minutes,
        int seconds)
    {
        return ((double)degrees % 360) + ((double)minutes / 60) + ((double)seconds / 3600);
    }

    /// <summary>
    /// Converts from degrees, minues, seconds to a string.
    /// </summary>
    /// <param name="degrees">The degrees.</param>
    /// <param name="minutes">The minutes.</param>
    /// <param name="seconds">The seconds.</param>
    /// <returns></returns>
    public static string ConvertSexagesimalToString(
        int degrees,
        int minutes,
        int seconds)
    {
        return String.Format(
            "{0}° {1}' {2}''",
            degrees.ToString(),
            minutes.ToString(),
            seconds.ToString());
    }

    /// <summary>
    /// Converts from a double to degrees, minues, seconds.
    /// </summary>
    /// <param name="value">The value to convert.</param>
    /// <param name="degrees">The degrees.</param>
    /// <param name="minutes">The minutes.</param>
    /// <param name="seconds">The seconds.</param>
    public static void ConvertDoubleToSexagesimal(
        double value,
        out int degrees,
        out int minutes,
        out int seconds)
    {
        degrees = (int)value;
        minutes = (int)((value - degrees) * 60);
        seconds = (int)((value - degrees - (minutes / 60)) * 3600);
    }
    #endregion Sexagesimal

    #region HMS
    /// <summary>
    /// Converts from hours, minues, seconds to a double.
    /// </summary>
    /// <param name="hours">The hours.</param>
    /// <param name="minutes">The minutes.</param>
    /// <param name="seconds">The seconds.</param>
    /// <returns></returns>
    public static double ConvertHMSToDouble(
        int hours,
        int minutes,
        int seconds)
    {
        return ((double)hours % 360) * 15 + ((double)minutes / 60) * 15 + ((double)seconds / 3600) * 15;
    }

    /// <summary>
    /// Converts from hours, minues, seconds to a string.
    /// </summary>
    /// <param name="hours">The hours.</param>
    /// <param name="minutes">The minutes.</param>
    /// <param name="seconds">The seconds.</param>
    /// <returns></returns>
    public static string ConvertHMSToString(
        int hours,
        int minutes,
        int seconds)
    {
        return String.Format(
            "{0}h {1}m {2}s",
            hours.ToString(),
            minutes.ToString(),
            seconds.ToString());
    }

    /// <summary>
    /// Converts from a double to hours, minues, seconds.
    /// </summary>
    /// <param name="value">The value to convert.</param>
    /// <param name="hours">The hours.</param>
    /// <param name="minutes">The minutes.</param>
    /// <param name="seconds">The seconds.</param>
    public static void ConvertDoubleToHMS(
        double value,
        out int hours,
        out int minutes,
        out int seconds)
    {
        double totalseconds = value / 15 * 3600;

        hours = (int)Math.Truncate(totalseconds / 3600);
        minutes = (int)Math.Truncate((totalseconds - hours * 3600) / 60);
        seconds = (int)Math.Truncate(totalseconds - (hours * 3600) - (minutes * 60));
    }
    #endregion HMS
}
 

So a conversion from Latitude or Longitude to a double would look something like this:

double latitude = GISUtilities.ConvertSexagesimalToDouble(100, 34, 20);
 
There are also methods in this library to convert between hours/minutes/seconds as well as the degree/minutes/seconds primarily used in geo-spatial calculations.
 

kick it on DotNetKicks.com

 

Posted in .Net | 4 Comments »

How to grayout an image in .Net

Posted by Dan Rigsby on 28th March 2008

Here is a handy method for making a grayscale version of an image.  I use this method a lot to grayout icons that I wish to show as disabled.  All you need to do is pass in the image and it will apply a grayscale over it.  The key to getting all of this to work is the ColorMatrix.  There is a detailed article about how this works on codeproject: http://www.codeproject.com/KB/GDI-plus/colormatrix.aspx.

public static void ApplyGrayscale(
    ref Image image)
{
    // Build color matrix set at 1/3
    ColorMatrix matrix = new ColorMatrix();
    matrix[0, 0] = 1/3f;
    matrix[0, 1] = 1/3f;
    matrix[0, 2] = 1/3f;
    matrix[1, 0] = 1/3f;
    matrix[1, 1] = 1/3f;
    matrix[1, 2] = 1/3f;
    matrix[2, 0] = 1/3f;
    matrix[2, 1] = 1/3f;
    matrix[2, 2] = 1/3f;

    // Create image attributes that will applied to the image
    ImageAttributes attributes = new ImageAttributes();
    attributes.SetColorMatrix(matrix);

    Graphics g = null;
    try
    {
        // Get the graphics object from the image
        g = Graphics.FromImage(image);

        // Redraw the image on the graphics object using the grayscale color matrix
        g.DrawImage(image,
            new Rectangle(0, 0, image.Width, image.Height),
            0,
            0,
            image.Width,
            image.Height,
            GraphicsUnit.Pixel,
            attributes);
    }
    finally
    {
        if (g != null)
        {
            g.Dispose();
        }
    }
}

 

Here are some sample before and after images (of my daughter Claire):

claire clairegray

 

Here is another example with a more typical line-of-business image:

disk_blue disk_bluegray

 

To make this easier to try out or use, I have wrapped the method into a executable as well.  You can download the source for this here: http://www.danrigsby.com/Files/Rigsby.ImageUtilities.Grayscale.zip

To run the program, compile the code and execute the exe file while passing in the source file name and the file name you want to save the new grayscaled image to, like this:

Rigsby.ImageUtilities.Grayscale.exe "c:\Claire.jpg" "c:\Claire-Gray.jpg"
 

Posted in .Net, Common Libraries | 9 Comments »

Disposable Base Class

Posted by Dan Rigsby on 15th March 2008

trashcanMany classes are built that implement System.IDisposable, which is a good thing.  This pattern makes for a good design to clean up your objects and can be used by the using statement to easily dispose of your objects.  This article already assumes that you know the basics of the Dispose Pattern. However sometimes having just a Dispose() method isn’t always enough.  Many times you a combination of a Disposed event, a void Dispose(bool disposing) method for use by a deconstructor, a boolean flag to check if the object IsDisposed, and maybe a method to check if the object is disposed that can throw an exception.  Some "best practices" often dictate that you should be using some of these additional things.  You may be writing this logic over and over again for each class, or you might start with a basic IDisposable pattern and weeks later you decide to refactor it to add in something like the boolean flag for IsDisposed.

After facing these same issues for awhile, I decided to put together a simple Diposable base class with all of the recommended patterns for using Disposable.  Of course, this can’t always be used since you might already have a base class.  But many times a class will derive from IDisposable and nothing else.  This is just screaming for a Disposable base class that encapsulates this logic!  For classes that already have a base class, I also have a code snippet to include everything that’s in the base class.

Here are the features of the Disposable Base Class and Code Snippet:

  1. void Dispose() Method - This is just the standard Dispose method that is defined in the IDisposable interface.
  2. void Dispose(bool disposing) Method - This method is called from the Dispose() method passing in true.  Its called from the deconstructor using false.  This is the method that you should override in your parent class and check if disposing is true before disposing of managed code.  The reason for this is that the deconstructor would have already disposed of the managed code, so you shouldn’t try to do it again.  If the deconstrutor called this method, you should only dispose of unmanaged code.
  3. void CheckDisposed() Method - This method is marked protected and is used by the parent class to check if the object is disposed.  It will throw an ObjectDisposedException if necessary.
  4. bool IsDisposed Property - A simple property to check whether or not this object has been disposed yet.
  5. Disposed Event - This event is fired when the object has been disposed.

To use the base class, you just override the Dispose(bool disposing) method. An example of this base class in use could look like this:

public class MyClass : Disposable
{
    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Dispose any managed code here
        }

        // Dispose any unmanaged code here

        base.Dispose(disposing);
    }
}

 

Here is the base class:

using System;
using System.ComponentModel;

namespace Rigsby
{
    /// <summary>
    /// Represents a basic disposable class.
    /// </summary>
    public abstract class Disposable : IDisposable
    {
        #region Private Properties
        private bool m_IsDisposed = false;
        #endregion Private Properties

        #region Public Properties
        /// <summary>
        /// Gets a value indicating whether this instance is disposed.
        /// </summary>
        /// <value>
        ///     <c>true</c> if this instance is disposed; otherwise, <c>false</c>.
        /// </value>
        [Browsable(false)]
        public bool IsDisposed
        {
            get
            {
                return m_IsDisposed;
            }
        }
        #endregion Public Properties

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="Disposable"/> class.
        /// </summary>
        public Disposable()
        {
        }

        /// <summary>
        /// Releases unmanaged resources and performs other cleanup operations before the
        /// <see cref="Disposable"/> is reclaimed by garbage collection.
        /// </summary>
        ~Disposable()
        {
            Dispose(false);
        }
        #endregion Constructors

        #region IDisposable Members
        private event System.EventHandler m_Disposed;

        /// <summary>
        /// Occurs when this instance is disposed.
        /// </summary>
        public event System.EventHandler Disposed
        {
            add
            {
                m_Disposed += value;
            }
            remove
            {
                m_Disposed -= value;
            }
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        public void Dispose()
        {
            if (!m_IsDisposed)
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            try
            {
                if (disposing)
                {
                    EventHandler handler = m_Disposed;
                    if (handler != null)
                    {
                        handler(this, EventArgs.Empty);
                        handler = null;
                    }
                }
            }
            finally
            {
                m_IsDisposed = true;
            }
        }
        #endregion IDisposable Members

        /// <summary>
        ///    <para>
        ///        Checks if the instance has been disposed of, and if it has, throws an <see cref="ObjectDisposedException"/>; otherwise, does nothing.
        ///    </para>
        /// </summary>
        /// <exception cref="ObjectDisposedException">
        ///    The instance has been disposed of.
        ///    </exception>
        ///    <remarks>
        ///    <para>
        ///        Derived classes should call this method at the start of all methods and properties that should not be accessed after a call to <see cref="Dispose()"/>.
        ///    </para>
        /// </remarks>
        protected void CheckDisposed()
        {
            if (m_IsDisposed)
            {
                string typeName = GetType().FullName;

                // TODO: You might want to move the message string into a resource file
                throw new ObjectDisposedException(
                    typeName,
                    String.Format(System.Globalization.CultureInfo.InvariantCulture,
                        "Cannot access a disposed {0}.",
                        typeName));
            }
        }
    }
}

Here is the code snippet version, or download it here.  If you use the snippet, you will want to manually change your class to derive from the IDisposable interface, then add this snippet.

<?xml version="1.0" encoding="utf-8"?> <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">   <CodeSnippet Format="1.0.0">     <Header>       <Title>IDisposable</Title>       <Shortcut>       </Shortcut>       <Description>Implements the IDisposable interface with additional best practices.</Description>       <Author>Dan Rigsby</Author>     </Header>     <Snippet>       <Code Language="csharp"><![CDATA[        #region IDisposable Members
        private bool m_IsDisposed = false;
        private event System.EventHandler m_Disposed;

        /// <summary>
        /// Gets a value indicating whether this instance is disposed.
        /// </summary>
        /// <value>
        ///     <c>true</c> if this instance is disposed; otherwise, <c>false</c>.
        /// </value>
        [System.ComponentModel.Browsable(false)]
        public bool IsDisposed
        {
            get
            {
                return m_IsDisposed;
            }
        }

        /// <summary>
        /// Occurs when this instance is disposed.
        /// </summary>
        public event System.EventHandler Disposed
        {
            add
            {
                m_Disposed += value;
            }
            remove
            {
                m_Disposed -= value;
            }
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        public void Dispose()
        {
            if (!m_IsDisposed)
            {
                this.Dispose(true);
                System.GC.SuppressFinalize(this);
            }
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            try
            {
                if (disposing)
                {
                    System.EventHandler handler = m_Disposed;
                    if (handler != null)
                    {
                        handler(this, System.EventArgs.Empty);
                        handler = null;
                    }
                }
            }
            finally
            {
                m_IsDisposed = true;
            }
        }

        /// <summary>
        ///    <para>
        ///        Checks if the instance has been disposed of, and if it has, throws an <see cref="ObjectDisposedException"/>; otherwise, does nothing.
        ///    </para>
        /// </summary>
        /// <exception cref="System.ObjectDisposedException">
        ///    The instance has been disposed of.
        ///    </exception>
        ///    <remarks>
        ///    <para>
        ///        Derived classes should call this method at the start of all methods and properties that should not be accessed after a call to <see cref="Dispose()"/>.
        ///    </para>
        /// </remarks>
        protected void CheckDisposed()
        {
            if (m_IsDisposed)
            {
                string typeName = GetType().FullName;

                // TODO: You might want to move the message string into a resource file
                throw new System.ObjectDisposedException(
                    typeName,
                    String.Format(System.Globalization.CultureInfo.InvariantCulture,
                        "Cannot access a disposed {0}.",
                        typeName));
            }
        }
        #endregion IDisposable Members]]></Code>     </Snippet>   </CodeSnippet> </CodeSnippets>

kick it on DotNetKicks.com

Posted in .Net, Common Libraries | 1 Comment »