Friday, June 11, 2010

C#, searching for an element in a list

The List class is mighty powerful. It can make an arraylist out of any class. The problem is that it's not always easy finding some internal class value in an object in that list.

Say I have an alarm class:
public class Alarms
{
public DateTime time;
public enum alarmType { major, minor };
public string originator;
}
And a lot of these are encapsulated in a list:
List alarmList;
If a user is looking at this list (probably in a listview) and has modified a value of an individual alarm in the list, how do we find that alarm in the list? (In my program, it's a temporary buffer which multiple threads write to and from)

Simply put, we use delegates.

If the user has extracted an alarm from the list called "al" and modified the values, and then wants to put it back to a list that has probably been modified and has new index values, use this:
int indexToLookFor = alarmList.FindIndex(delegate(Alarms alarm)
{
return alarm.time == al.time && alarm.alarmType == al.alarmType && alarm.originator == al.originator;
});
if (indexToLookFor >= 0)
{
//the alarm has been looked at, make it a minor one
alarmList[indexToLookFor].alarmType = alarmType.minor;
}
It uses the FindIndex function of , comparing each variable of the class. Granted, you could write your own For loop to do it, but this is much quicker, and in my opinion, more grand.

Tuesday, June 8, 2010

Catching the enter key in a C# textbox

It's simple, but useful:

     private void textBoxProductKey_KeyPress(object sender, KeyPressEventArgs e)
             {
                 //pressing the enter key, ladies.
                 if (e.KeyChar == 13) {
                     //do your thing

                 }
                 e.Handled = true;
             }


The keyboard code for enter is 13.

Thursday, June 3, 2010

C# Bitmap manipulation

I tend to do a bit of image processing in C#. Using SetPixel() and GetPixel() is such a time consuming process, especially when you are image processing live video streams.

The solution? Do it in pointers. I could go into detail using pointers in C#, but that's everywhere else on the net. So just know that you do it in Unsafe mode. Don't forget to enable Unsafe mode. Go to Project>Properties>Build and check Allow Unsafe Code in Visual Studio.

The following block of code will then enable you to edit a single pixel:
        Bitmap theImage = new Bitmap("C:\\theimage.jpg");
        int stride; //stride of the image for processing (basically padding at the sides of images
        BitmapData bmData = theImage.LockBits(new Rectangle(0, 0, theImage.Width, theImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        stride = bmData.Stride;
        System.IntPtr Scan0 = bmData.Scan0; //pointer to the pixels of the image
        int width = theImage.Width;
        int height = this.Height;
        unsafe
        {
            //code is "unsafe" as it has pointer operations
            //don't freak out too much, "unsafe" doesn't mean this will blow up in your face
            byte red, green, blue;
            byte* p = (byte*)(void*)Scan0;  //pointer to the first pixel of the bitmap
            byte* pOriginal = (byte*)(void*)Scan0;
            int nOffset = stride - width * 3;    //offeset increment for each line
            p = pOriginal + 3 * (x) + stride * y;
            blue = p[0];
            green = p[1];
            red = p[2];
            //do whatever
        }
        theImage.UnlockBits(bmData);
This will do one pixel, of a 24 bits per pixel bitmap, with the Byte* variables blue, green and red being that particular colour of the pixel from 0 to 255. The variables are:
  • theImage - a Bitmap file that you are manipulating
  • stride - how wide the image is, in padding terms
  • bmData - the raw bitmap data
  • Scan0 - pointer to the first bite of the pixel
  • p - the byte address of the individual pixel you want to work on
  • pOriginal - the byte address of the first pixel. If you are doing iterative work, it's easier just to have this as a pointer variable for the pointer math
  • x and y - integer values for the x and y co-ordinate of the pixel being set
I tend to do iterations only over regions of interest, so I do iterative loops which just assign a new value for p (based off of x and y) and change the individual blue, green and red colours. To change the values of the colours, use code such as:

blue = (byte)255;
green = (byte)0;
red = byte(0);
That will make the pixel blue.