imageComponent.NET - image processing .NET assemblies
Image Filter Notification
After version 2.1, image filter in PhotoController starts to provide some events. If you have known about delegate events very well, please skip the first section. The second section describes the filter event handler and delegate function. The third section describes how to write an event handler when using a Filter class. The fourth section talks about how to turn on the event handler in your custom filter class.

1. Introduction - What's event delegate?

I don't want to repeat what Microsoft have explained (see Events and Delegates), if you don't have any experience of it, I will use a much easier way to explain.

Suppose I am cooking, you "delegate" an event to me to let me tell you when I am done. So, when I finish cooking, I will leave the kitchen, kick your ass, and yell at you, "It's Time To Eat Now!" (if those actions were defined in the event handler). Yes, when you "delegate" an event to me, you also need to define an "event handler" to me so that I know how to perform the delegation.

Another example is, suppose I am still cooking (because I love it), you want me to keep you posted, otherwise I will probably sneak away to play WII or write my program enthusiastically. Therefore, you "delegate" an "Update" event to me, and define the action, "speak loudly" the status of cooking. Now once I finish something, I must speak loudly what I do. I will keep yelling, "I AM PEELING THE POTATO", "I AM WASHING THE LETTUCE", "I AM ADDING TRIPLE SALT INTO YOUR SOUP", etc. Then, you always know what I am doing.

I hope the above examples make sense. Usually, a class provides a certain events, you assign an event handler to it to define the behaviors. An event handler has a type, which is an delegate function. Each event handler (delegate function) might be different in different scenario.

2. Event Handler and Delegate Function in Filter

Currently, PhotoController has only one delegate function PercentageHandler, which define the event to update the image processing status.

BaseFilter provides the corresponding event handler PercentageChanged, which will be triggered when the filter needs to update the processing status.

3. How to write an event handler to a filter class?

First, after you initialize a filter class, you need to delegate (assign) an event handler to it. If you use Visual Studio.NET, the editor will help you to complete the delegate function part.

Suppose you have an control Progress Bar, which you can use it to show the filter progress. By doing that, you can keep your end-users posted (giving feedback), in case some filters require a period of time (due to the image size is too large or the algorithm is slow unavoidablly).

In your program, after you declare the filter class, you need to assign an event handler to it as follows:

C#

   1:  InvertColorFilter filter = new InvertColorFilter();
   2:   
   3:  filter.PercentageChanged += new PercentageHandler(filter_PercentageChanged);
   4:   
   5:  private void filter_PercentageChanged(int percentage)
   6:  {
   7:      barProgress.Value = percentage;
   8:  }

VB.NET

   1:  Dim filter As New InvertColorFilter()
   2:   
   3:  AddHandler filter.PercentageChanged, AddressOf PercentageChanged
   4:   
   5:  Private Sub PercentageChanged(ByVal percentage As Integer)
   6:      Me.ProgressBar1.Value = percentage
   7:  End Sub

How to write the EventHandler to update progress

All filter classes have been set to update the processing status if the event is assigned a handler. But when you are writing the custom filter, you need to know how to update the status during your algorithm operation.

If you inherit BaseColorFilter or BaseOffsetFilter, and you only override transformColor or transform method without modifying ApplyFilter itself, then you are fine, you don't need to worry about the update. Those two classes have handled it in ApplyFilter method.

But if you inherit BaseFilter, that means you have to override ApplyFilter and put your processing algorithm there, in that case, you need to trigger the update. BaseFilter provides two new properties and one method that can be used to update processing status.

  1. NeedUpdatePercentage - returns true if the event has been assigned a handler
  2. PercentageChangedHandler - returns the handler itself, it is useful when you are using another class to process the algorithm, you can pass the whole event handler to it
  3. UpdatePercentage - this method is called to update the processing percentage

Because in the descendant of BasseFilter, you can not access the event handler directly, the above two properties and one method can basically help you in different situations.

The following sample code is from the customer filter FastEdgeDetect. From the algorithm, it scans the pixel by walking through column to row, so it loops the x-axis then the y-axis. The best place to update status is after processing y-axis and using the current x-aix coordiante divide by the width. Then call the method to update percentage. To avoid unneccessary calculation, you might want to see if NeedUpdatePercentage first.

C#

   1:  protected override void ApplyFilter()
   2:  {
   3:      // store the bitmap information first
   4:      int width = DrawArea.Width;
   5:      int height = DrawArea.Height;
   6:      int startX = this.DrawArea.Left;
   7:      int startY = DrawArea.Top;
   8:   
   9:      for (int x = startX ; x < width; x++)
  10:      {
  11:          for (int y = startY; y < height; y++)
  12:          {
  13:              if (x + 2 < width && y + 2 < height)
  14:              {
  15:                  Color offset = getPixel(x + 2, y + 2);
  16:                  Color current = getPixel(x, y);
  17:                  // apply the algorithm
  18:                  byte red = (byte)(current.R + (128 - offset.R));
  19:                  byte green = (byte)(current.G + (128 - offset.G));
  20:                  byte blue = (byte)(current.B + (128 - offset.B));
  21:   
  22:                  Color newColor = Color.FromArgb(red, green, blue);
  23:                  setPixel(x, y, newColor);
  24:              }
  25:          }
  26:   
  27:          // tell the event handler what the current status of this processing
  28:          if (this.NeedUpdatePercentage)
  29:          {
  30:              int percent = (int)((x / (width * 1.0)) * 100);
  31:              UpdatePercentage(percent);
  32:          }
  33:   
  34:      }
  35:  }

VB.NET

   1:  Protected Overrides Sub ApplyFilter()
   2:   
   3:      Dim width As Integer = DrawArea.Right
   4:      Dim height As Integer = DrawArea.Bottom
   5:      Dim startX As Integer = DrawArea.Left
   6:      Dim startY As Integer = DrawArea.Top
   7:      Dim x As Integer
   8:      Dim y As Integer
   9:   
  10:      For x = startX To width
  11:          For y = startY To height
  12:              If (x + 2 < width And y + 2 < height) Then
  13:                  Dim offset As Color = getPixel(x + 2, y + 2)
  14:                  Dim current As Color = getPixel(x, y)
  15:                  Dim red As Byte
  16:                  Dim blue As Byte
  17:                  Dim green As Byte
  18:   
  19:                  red = IntToByte(current.R + (128 - offset.R))
  20:                  green = IntToByte(current.G + (128 - offset.G))
  21:                  blue = IntToByte(current.B + (128 - offset.B))
  22:   
  23:                  Dim newColor As Color = Color.FromArgb(red, green, blue)
  24:                  setPixel(x, y, newColor)
  25:              End If
  26:          Next
  27:   
  28:          If (NeedUpdatePercentage) Then
  29:              Dim percent As Integer
  30:              percent = CInt((x / (width * 1.0)) * 100)
  31:              UpdatePercentage(percent)
  32:          End If
  33:      Next
  34:  End Sub
[Back to Top]
Comments

If you feel this page can be improved or has any mistake, please enter your valuable opinion here. Or if you cannot find the information you are after, feel free to suggest a subject too. I appreciate any voice.

Your Name:
  
Your Email Address:
  
Comments: