I have a relatively simple threshold function that’s using unsafe code. This works a treat in Windows, however, in Mono on linux, no thresholding takes place. It’s difficult to debug as it’s on Linux only, I’ve checked the bitsPerPixel is correct along with the height h
, width w
and stride ws
are all correct as well.
What else can I do to narrow it down, or is there a common gotcha here?
public void threshold(Bitmap bmp, int thresh) { var bitsPerPixel = Image.GetPixelFormatSize(bmp.PixelFormat) / 8; BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat); unsafe { byte* p = (byte*)(void*)bmData.Scan0.ToPointer(); int h = bmp.Height; int w = bmp.Width; int ws = bmData.Stride; for (int i = 0; i < h; i++) { byte* row = &p[i * ws]; for (int j = 0; j < w * bitsPerPixel; j += bitsPerPixel) { for (var k = 0; k < bitsPerPixel; k++) { row[j + k] = (byte)((row[j + k] > (byte)thresh) ? 255 : 0); } } } } bmp.UnlockBits(bmData); }
Advertisement
Answer
Set ImageLockMode
to ReadWrite
:
BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
Example:
public unsafe void Threshold(Bitmap bmp, int thresh) { var bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); var bitsPerPixel = Image.GetPixelFormatSize(bmp.PixelFormat); var p = (byte*)bmData.Scan0.ToPointer(); for (int i = 0; i < bmData.Height; ++i) { for (int j = 0; j < bmData.Width; ++j) { byte* data = p + i * bmData.Stride + j * bitsPerPixel / 8; data[0] = (byte)((data[0] > thresh) ? 255 : 0); data[1] = (byte)((data[1] > thresh) ? 255 : 0); data[2] = (byte)((data[2] > thresh) ? 255 : 0); } } bmp.UnlockBits(bmData);