1

I am working with some image processing code in C#. Because performance is critical, I'm doing this in unsafe code with pointers.

Here's some code to precede my question:

Rectangle Image_Rectangle = new Rectangle(0, 0, MyImage.Width, MyImage.Height);
BitmapData Image_Data = MyImage.LockBits(Image_Rectangle, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
// ... x and y nested for-loops to work with each pixel
Byte* PixelRow = (Byte*)Image_Data.Scan0 + (y * Image_Data.Stride);

Once I have the above Byte pointer, I can set its values like so:

PixelRow[(x * 3) + 2] = 255;
PixelRow[(x * 3) + 1] = 255;
PixelRow[(x * 3)] = 255;

However, I would prefer to access these as an array:

Byte[] RGB = { PixelRow[(x * PIXEL_SIZE) + 2], PixelRow[(x * PIXEL_SIZE) + 1], PixelRow[(x * PIXEL_SIZE) + 0] };

RGB[0] = 255;
RGB[1] = 255;
RGB[2] = 255;

The problem is when I try to assign the value, I sense I'm not working with the actual pointer anymore. Once I unlock bits, the resulting bitmap is unchanged (when using the array method).

I'm pretty new to pointers, can anyone help explain what's going on and how to properly maintain pointers through the use of an array?

2
  • Are you sure you are not reinventing the wheel? Commented Apr 28, 2011 at 1:41
  • 1
    I haven't worked with pointers in C#, but my suspicion is that you are running into an issue with capturing the pointer versus the value being pointed to. The first way of accessing likely works because it is computing the memory address and then setting the value 255 at that location. In the second style, I believe it is dereferencing the pointer and storing the value in a new Byte array. So when you set the value you setting it to a stored copy on the stack, and not the actual memory on the heap you wanted to change. Commented Apr 28, 2011 at 1:45

3 Answers 3

1
Byte[] RGB = { PixelRow[(x * PIXEL_SIZE) + 2], 
               PixelRow[(x * PIXEL_SIZE) + 1], 
               PixelRow[(x * PIXEL_SIZE) + 0] };

You are creating an array of bytes based on the values that PixelRow[..] is pointing to - since these are bytes - a value type - you are creating a copy for each byte and the resulting array is completely separate from the image they came from.

Sign up to request clarification or add additional context in comments.

Comments

1

Guess you can't leave code in comments :) Try something like

 Byte*[] RGB = { &PixelRow[(x * PIXEL_SIZE) + 2], 
                 &PixelRow[(x * PIXEL_SIZE) + 1], 
                 &PixelRow[(x * PIXEL_SIZE) + 0] };

--4/29 Edit

Another approach you could try is to get a pointer to the index of the array where the pixel you are concerned with starts. Then use that with array notation to access and alter the Red, Green, and Blue byte values you are concerned with. Now this assumes that your pixels are stored in the array in sequential order, but you could do that as follows:

Byte* RGB = &PixelRow[x * PIXEL_SIZE];
RGB[0] = (byte)255;
RGB[1] = (byte)255;
RGB[2] = (byte)255;

4 Comments

Unfortunately this didn't work, attempting to assign a value like this RGB[0] = 255; results in an error (cannot convert int to byte*).
You'll likely have to dereference the pointer in the array to set the value. Try doing: *RGB[0] = (byte)255;
@JYelton where you able to get this working? I did some tests in LinqPad and both my approaches worked for me.
I think I just did it without the array, I will have to revisit your suggestions if I work on that part of the project again. Thanks!
0

You can override the index operator and have it do what you like.

More on this here:

http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/9bec45ef-b471-4dda-92b0-e6c99e82c356/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.