Randy Hall
Randy Hall

Reputation: 8167

C# Convert or compare int to (unsafe) byte*

Original Scenario

I massively misunderstood my own code, and this scenario is invalid.

This is way out of my normal wheelhouse, so I'm going to explain best I can.

I have a user-set color code. Example:

int R = 255;
int G = 255;
int B = 255; 

And I have a lot of large images where I need to check the color of pixels at certain sets of coordinates against the user-set color. I can successfully get the byte* of any pixel in an image, and get the values I expect.

I do this using BitmapData from Bitmap.LockBits(...). My understanding is that locking will be important to performance reasons. There will be a great many instances of this being used across a very large collections of images, so performance is a major consideration.

For those same performance reasons I'm trying to avoid converting the retrieved pixel-colors represented by unsafe bytes to integers - I'd much rather convert my int to a byte one time and use that for the likely millions of pixels this will be run against each time it is invoked.

However... I cannot figure out how to get any of my user-set integers into an unsafe byte (byte*) and compare it to the unsafe byte retrieved from a pixel.

The unsafe byte (byte*) was the 8-bit pointer of the data of the pixel (at least, that's how I understand it) but I am getting the individual colors as regular old bytes.

byte* pixel = //value here pulled from image;
pixel[2] //red value byte
pixel[1] //green value byte
pixel[0] //blue value byte

So I don't need to convert my ints to unsafe bytes ...pointers?..., just a simple Converter.ToByte(myInt).


The real question

But since I think this is still possibly a valid question outside my scenario, I'm going to leave this part up for someone to answer and hopefully help someone in the future:

How do you take any given int in C# and compare it to an "unsafe byte" pointer 'byte*'?

Upvotes: 1

Views: 1923

Answers (2)

Let us open a open a bitmap and process each pixel

//Note this has several overloads, including a path to an image
//Use the proper one for yourself
Bitmap b = new Bitmap(_image);

//Lock(and Load baby) 
BitmapData bData = b.LockBits(new Rectangle(0, 0, _image.Width, _image.Height), ImageLockMode.ReadWrite, b.PixelFormat);

//Bits per pixel, obviously
byte bitsPerPixel = Image.GetPixelFormatSize(bitmap.PixelFormat);

//Gets the address of the first pixel data in the bitmap.
//This can also be thought of as the first scan line in the bitmap.
byte* scan0 = (byte*)bData.Scan0.ToPointer();

for (int i = 0; i < bData.Height; ++i)
{
    for (int j = 0; j < bData.Width; ++j)
    {
        byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;
        //data is a pointer to the first byte of the 3-byte color data
        //Do your magic here, compare your RGB values here 
         byte R = *b;     //Dereferencing pointer here
         byte G = *(b+1); 
         byte B = *(b+2); 
    }
}
//Unlocking here is important or memoryleak
b.UnlockBits(bData);

Upvotes: 0

Jonathon Chase
Jonathon Chase

Reputation: 9704

You would just want to dereference the byte pointer and compare it to the integer.

unsafe void Main()
{
    byte x = 15;
    int y = 15;
    Console.WriteLine(AreEqual(&x, y)); // True
}

public unsafe bool AreEqual(byte* bytePtr, int val) {
    var byteVal = *bytePtr;
    return byteVal == val;
}

Upvotes: 1

Related Questions