Friday, December 24, 2010

Silverlight: loading a WriteableBitmap from file

I’ve just spent quite some time trying to do something that seems very simple: embedding an image in a Silverlight application and loading this image into a WriteableBitmap (because I need to read the values of the individual pixels).

My first attempt was to add the image to my project as a resource and use the following code:

Uri uri = new Uri("Images/Texture.jpg", UriKind.Relative);
BitmapImage imageSource = new BitmapImage(uri);
WriteableBitmap bitmap = new WriteableBitmap(imageSource);  // EXCEPTION

However, an exception is thrown on the last line. Luckily the internet came to the rescue, and these two great site suggest basically the same solution:

  • Using BitmapCreateOptions.None to make sure the bitmap begins to load immediately.
  • Subscribing to events to know when the image has actually loaded.

However the proposed solution did not work in my case because the image fails to load with an AG_E_NETWORK_ERROR error.

In the end I took a different approach: I load the resource using Application.GetResourceStream so I’m sure that the data is completely loaded before it is handed to the WriteableBitmap. This is the code:

StreamResourceInfo sri = Application.GetResourceStream(new Uri("Images/Texture.jpg", UriKind.Relative));
 
BitmapImage src = new BitmapImage();
src.SetSource(sri.Stream);
WriteableBitmap image = new WriteableBitmap(src);

In my case it has the advantage of being synchronous which makes the overall code much simpler (but I understand that asynchronous behavior may often be better in a web-context).

When adding your image to your Silverlight project, the build action should be set to ‘Content’ instead of ‘Resource’. This means that the image will not be included in the dll, but it will be stored in the xap-file. You can check this by renaming the xap-file to zip and looking at the content.

So there are some non-intuitive steps involved when trying to accomplish this simple task. Hopefully this post can be helpful if someone else has this problem.

Friday, December 05, 2008

Saving and restoring GDI+ state

When you create complex drawing code, you probably will split this over multiple methods and pass the Graphics-object between these methods. But because the Graphics-object contains state, all changes that you apply in a method will be propagated to the other methods as well. Often this is not what you want.

The common way to work around this is to reset all the changes that you made at the end of the method:

   1: void PaintBackGround(Graphics g)
   2: {
   3:     SmoothingMode oldSmoothingMode = g.SmoothingMode;
   4:     try
   5:     {
   6:         g.SmoothingMode = SmoothingMode.AntiAlias;
   7:         ...
   8:     }
   9:     finally
  10:     {
  11:         g.SmoothingMode = oldSmoothingMode;
  12:     }
  13: }

But if your code changes a lot of properties this will become cumbersome. In these cases it is simpler to save and restore the entire Graphics-state like this:

   1: void PaintBackGround(Graphics g)
   2: {
   3:     GraphicsState oldState = g.Save();
   4:     try
   5:     {
   6:         g.SmoothingMode = SmoothingMode.AntiAlias;
   7:         ...
   8:     }
   9:     finally
  10:     {
  11:         g.Restore(oldState);
  12:     }
  13: }

Wednesday, November 26, 2008

Creating a single-instance application

A lot has been written on the internet on how to create a single-instance application in C#. The proposed implementations fall into three categories:

  • Check if a process with the same name is already running (using GetProcessesByName). This is plain wrong because it needs administrator privileges. Furthermore it will not work if there is another process that happens to have the same name as your process.
  • Using the Microsoft.VisualBasic namespace (as explained here). This probably works OK (I have never done this), but it feels a bit wrong. Note that this approach is promoted in the book ‘Windows Forms 2.0 Programming’.
  • Using a Mutex.

Personally I think that the last approach is best, but there are some details that you need to get correct if you want to rely on this. This is the pattern that I propose:

   1: static class Program
   2: {
   3:     static Mutex s_Mutex;
   4:  
   5:     /// <summary>
   6:     /// The main entry point for the application.
   7:     /// </summary>
   8:     [STAThread]
   9:     static void Main()
  10:     {
  11:         bool instantiated;
  12:         // WARNING: you need to replace the GUID in this string!
  13:         s_Mutex = new Mutex(false, "Local\\MyAppName{A6F214AB-669D-41B2-9F30-8DD5E5AC9AE1}", out instantiated);
  14:         if (!instantiated)
  15:         {
  16:             MessageBox.Show("The application is already running");
  17:             return;
  18:         }
  19:  
  20:         Application.EnableVisualStyles();
  21:         Application.SetCompatibleTextRenderingDefault(false);
  22:         Application.Run(new Form1());
  23:     }
  24: }

The pattern is applied to a Winforms application, but of course it can be applied to any type of application.

For those who don’t know what a mutex is: it is a Windows kernel-object that can be used for synchronization between threads and processes. The proposed pattern tries to create a mutex with a certain name and checks if this mutex already existed. If it did, this means that our process was already started.

Here are the details that are important:

  • The mutex must be declared static, because we have to make sure that the garbage collector will never dispose it.
  • The name of the mutex should contain a GUID, which ensures that no other application uses the same name. If you don’t know how to create a GUID, click here.
  • The mutex is local, which means that every user that is logged on can create his own instance. If you don’t want this, simply ommit the ‘Local\\’.
  • The mutex contains the name of the application. As a general guideline, I think that named kernel objects should have a descriptive name. This makes it easier when debugging problems: using tools such as SysInternal’s WinObj, you can look at the state of all the kernel objects. If your object has a proper name this will be much simpler.

Wednesday, November 19, 2008

GDI+ objects should be disposed

When a Winforms-control needs to do custom painting, this is typically done by overriding the OnPaint-method like this:

   1: protected override void OnPaint(PaintEventArgs e)
   2: {
   3:     base.OnPaint(e);
   4:  
   5:     Graphics g = e.Graphics;
   6:  
   7:     // WARNING: this code should be avoided because it does not dispose the GDI+ objects
   8:     g.FillRectangle(new SolidBrush(Color.Black), this.ClientRectangle);
   9:     TextRenderer.DrawText(g, "Hello world!", new Font(FontFamily.GenericSansSerif, 10f), new Point(10, 10), Color.White);
  10:     g.DrawLine(new Pen(Color.White), new Point(0, 0), new Point(100,100));
  11: }

On the internet you will find lots of example code that does custom drawing like this. The problem is that every time this code is executed (and in GUI this can be a lot!), a bunch of GDI+ objects are created that are not disposed. Eventually the garbage collector will kick in and will dispose all these objects. This is to be avoided however:

  • This puts a lot of stress on the garbage collector.
  • These objects will be cleaned up in two fazes which will impact performance even more.
  • GDI+ handles are limited resources, but the garbage collector is only invoked if your application needs more memory. It is not unlikely that your code uses a lot of GDI+ handles but does not consume a lot of memory. This may mean that the garbage collector never executes, and your code may consume a huge amount of GDI+ handles.
    This issue was especially problematic before GC.AddMemoryPressure() was added in .NET 2.

The obvious solution is to dispose the GDI+ objects when they are not needed anymore:

   1: protected override void OnPaint(PaintEventArgs e)
   2: {
   3:     base.OnPaint(e);
   4:  
   5:     Graphics g = e.Graphics;
   6:  
   7:     // Much better: less stress on the garbage collector
   8:     using (SolidBrush brush = new SolidBrush(Color.Black))
   9:     using (Font font = new Font(FontFamily.GenericSansSerif, 10f))
  10:     using (Pen pen = new Pen(Color.White))
  11:     {
  12:         g.FillRectangle(brush, this.ClientRectangle);
  13:         TextRenderer.DrawText(g, "Hello world!", font, new Point(10, 10), Color.White);
  14:         g.DrawLine(pen, new Point(0, 0), new Point(100,100));
  15:     }
  16: }

This code is good but we can make it even better. Note that every time the code is executed, new GDI+ objects are created and disposed. In this particular case this is a waste because the objects will be identical every time. It would be better to create the objects only once, and reuse them every time.

It seems that the Winforms-designers at Microsoft also had this idea, because they already cache the commonly used brushes and pens in the Brushes and Pens classes. For the Font-object we need to do this ourselves:

   1: static readonly Font s_Font = new Font(FontFamily.GenericSansSerif, 10f);
   2:  
   3: protected override void OnPaint(PaintEventArgs e)
   4: {
   5:     base.OnPaint(e);
   6:  
   7:     Graphics g = e.Graphics;
   8:  
   9:     g.FillRectangle(Brushes.Black, this.ClientRectangle);
  10:     TextRenderer.DrawText(g, "Hello world!", s_Font, new Point(10, 10), Color.White);
  11:     g.DrawLine(Pens.White, new Point(0, 0), new Point(100,100));
  12: }

Notice that our Font-instance is declared as static because it can be reused when there are many instances of our control.

Of course this technique can only be used if the GDI+ objects are the same every time. If they are highly dynamic then you will have to create a new object every time (this may occur if you are drawing a part of an animation). But don’t forget to dispose these objects with the using-statement.

Wednesday, November 12, 2008

A Winforms-control should not subscribe to its own events

Each Winforms-control defines many events that can be used to receive all kinds of notifications. Often I see that a control subscribes to its own events, for example:

   1: // this code is added by the designer in the InitializeComponent() method
   2: this.Load += new System.EventHandler(this.Form1_Load);
   3:  
   4: private void Form1_Load(object sender, EventArgs e)
   5: {
   6:     ...
   7: }

This will work OK, but events are conceptually not so simple. They are needed when you need a loose coupling between the publisher and the subscriber. This makes no sense if the publisher and the subscriber are the same control.

There is an alternative that is much simpler: for each event, there is also a virtual method that can be overridden:

   1: protected override void OnLoad(EventArgs e)
   2: {
   3:     base.OnLoad(e);
   4:  
   5:     ...
   6: }

This alternative will also have a slightly better performance. However, you should not forget to call the base-implementation (luckily, this call will be added automatically by IntelliSense). The base-implementation will raise the event, so if you omit this then the other parts of the code will not receive this event from your control.

Wednesday, November 05, 2008

Casting an array of value types

Warning ahead: this article explains a dirty trick that should only be used in very specific circumstances (when memory conditions are low). I’ve personally seen this used when loading a large image from file (as a byte array) and needing to pass this array to a piece of legacy code that only accepts an array of shorts. Due to the size of the image, it was not feasible to copy the data.

Casting arrays of value types can be problematic. Image that you need to cast a large array of unsigned integers to an array of signed integers.

Our first experiment might be like this:

   1: static int[] Cast(uint[] input)
   2: {
   3:     int[] result = new int[input.Length];
   4:     
   5:     Array.Copy(input, result, input.Length);    // throws ArrayTypeMismatchException
   6:  
   7:     return result;
   8: }

This does not work. We get an ArrayTypeMismatchException because the two types are not compatible (the rules for compatible types are explained here).

The solution is to use the Marshal.Copy() method. This requires unsafe code however.
Here is an example:

   1: static unsafe int[] Cast(uint[] input)
   2: {
   3:     int[] result = new int[input.Length];
   4:  
   5:     fixed(uint* pInput = input)
   6:     {
   7:         Marshal.Copy(new IntPtr(pInput),result,0, input.Length);
   8:     }
   9:  
  10:     return result;
  11: }

This seems to work, but instead of casting the array we really made a copy of the array. The differences are subtle but can be important:

  • the copy requires its own memory. If the array is very large, this can be a problem. I’ve encountered situations (e.g. in image processing) where this was not acceptable.
  • when the copy is modified, the original array is left untouched. This is not what should happen when we cast a variable.

Using a dirty trick it is possible to cast an array of value types without copying the data. Look at this sample code:

   1: // WARNING: this is a dirty trick. Use at your own risk!
   2: static int[] Convert(uint[] input)
   3: {
   4:     Converter converter = new Converter();
   5:     converter.UInts = input;
   6:     return converter.Ints;
   7: }
   8:  
   9: [StructLayout(LayoutKind.Explicit)]
  10: struct Converter
  11: {
  12:     [FieldOffset(0)]
  13:     public int[] Ints;
  14:  
  15:     [FieldOffset(0)]
  16:     public uint[] UInts;
  17: }

We’re using a Converter-struct that uses some interop-magic to define two fields that map to the same location in memory. Now we can access the same data as an int[] or as an uint[]. The data is not copied in any way!

Note that this is a dirty trick: we fool the compiler into thinking that the type of the array is changed but it really is not. You can verify this by calling GetType() on the returned array: it will return System.UInt32[].

This trick can be used in other situations as well, for instance to access an array of integers as an array of bytes (without copying the data).

Warning: if the size of the array to be converted is reasonably small, you should just copy the data! Only use this trick if you really cannot afford to copy the data! This trick violates the type-safety of the runtime and is not guarantee to work in all situations or in future versions of .NET!

Wednesday, October 29, 2008

Removing items from a collection

A common coding pattern is removing items from a collection based on the value of the items. The simplest way to do this is to enumerate the collection, and remove all the items that you don't want.

Code example:

   1: List<string> colors = new List<string>();
   2: colors.Add("red");
   3: colors.Add("green");
   4: colors.Add("blue");
   5:  
   6: foreach (string color in colors) // WARNING: this code will throw an exception
   7: {
   8:     if (color == "green") colors.Remove("green");
   9: }

However, doing this will throw this exception: System.InvalidOperationException: Collection was modified; enumeration operation may not execute. It seems that the enumerator is invalid after the collection has been modified.

There are several ways to work around this behavior.

1 Store the items to be removed in a temporary collection

This approach is really simple: instead of immedeately removing the items, we keep them in a separate collection. In the end, after the original list has been enumerated, we remove all these items.

Code example:

   1: List<string> colors = new List<string>();
   2: colors.Add("red");
   3: colors.Add("green");
   4: colors.Add("blue");
   5:  
   6: List<string> itemsToRemove = new List<string>();
   7: foreach (string color in colors)
   8: {
   9:     if (color == "green") itemsToRemove.Add("green");
  10: }
  11:  
  12: foreach (string itemToRemove in itemsToRemove) colors.Remove(itemToRemove);

In most situations this approach works very well. Only in very large collections, the itemsToRemove collection may become very big and consume a lot of memory. In my experience this is seldom the case.

2 Iterate the collection from back to front

This alternative uses a for-loop to iterate the collection from the back to the front.

Code example:

   1: List<string> colors = new List<string>();
   2: colors.Add("red");
   3: colors.Add("green");
   4: colors.Add("blue");
   5:  
   6: for (int counter = colors.Count - 1; counter >= 0; counter--)
   7: {
   8:     if (colors[counter] == "green") colors.RemoveAt(counter);
   9: }

Here we do not need a temporary collection. It is also slightly more efficient because we can remove the item based on its index. This means that the collection does not have to search for the item that has to be removed (as was the case in the first approach).

3 Using a predicate

The third alternative is only available from .NET 2 onwards. The List-collection implements a RemoveAll() method that takes a predicate as a parameter. Simply put, a predicate is a delegate that is used for filtering. In this case, the predicate returns true for each item that needs to be removed.

In this code example, the predicate is implemented as an anonymous method:

   1: List<string> colors = new List<string>();
   2: colors.Add("red");
   3: colors.Add("green");
   4: colors.Add("blue");
   5:  
   6: colors.RemoveAll(delegate(string color)
   7: {
   8:     return color == "green";
   9: });

This approach has some benefits:

  • It is self-documenting.
  • We don’t have to worry about the performance, we can assume that the RemoveAll() method is implemented in the most efficient way. If the internals of the collection-class would later change, the RemoveAll() method will likely be changed as well to keep the best performance.