Speed. Copy bitmap data into array or work with it directly?
I am using a class LockedBitmap
that makes it easy to work with raster data in C #. It is currently copying data into a local array byte[]
, which then accesses its class methods to get / set pixel color values.
Is this faster or better than accessing the locked bitmap data directly via a pointer? Is a copy required?
Edit: I am not asking if its possible to work with raster data directly, I work with this every day. I'm just asking for a comparison between the two methods and, if necessary, for copying pixel data.
Copying pixel data to temp array:
// create byte array to copy pixel values
int step = Depth / 8;
Pixels = new byte[PixelCount * step];
Iptr = bitmapData.Scan0;
// Copy data from pointer to array
Marshal.Copy(Iptr, Pixels, 0, Pixels.Length);
Direct reading of pixel values:
byte* p = (byte*)(void*)bmData.Scan0.ToPointer();
int ws = bmData.Stride;
byte* row = &p[i * ws];
byte Gcolor = row[j];
byte Bcolor = row[j + 1];
byte Rcolor = row[j + 2];
source to share
Is this faster or better than accessing the locked bitmap data directly via a pointer?
Not. This requires an additional copy operation and then another operation to copy the processed values back to the bitmap.
Is a copy required?
Only in an environment where code is unsafe
not desired or available.
source to share
You can definitely work directly on the bitmap data without copying it. Here is some code I used to pull the 16bpp client gray-box format into the rendered bitmap:
Rectangle rect = new Rectangle(0, 0, bmOut.Width, bmOut.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmOut.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmOut.PixelFormat);
IntPtr ptr = bmpData.Scan0;
Byte[] bytes;
bytes = rawIn.ReadBytes(framesize);
for (int x = 0; x < bytes.Length; x += 2)
{
short[] rgb = new short[3];
int value = bytes[x + 1] * 256 + bytes[x];
//value = value / 32;
value = iMax * (value - iMin) / (iMax - iMin);
if (value < iMin)
{
value = iMin;
}
else if (value > iMax)
{
value = iMax;
}
value = 65536 * (value - iMin) / (iMax - iMin);
rgb[0] = rgb[1] = rgb[2] = (short)(value);
System.Runtime.InteropServices.Marshal.Copy(rgb, 0, ptr + (x) * 3, 3);
}
bmOut.UnlockBits(bmpData);
Key LockBits
andUnlockBits
As a quick explanation, I am reading 16bpp from file in bytes
, restoring 16 bits in value
. Then, using external settings iMin
and iMax
to get the correct shading. Then take this single one value
and plot it RGB and use Marshal.Copy
to place it in a bitmap.
source to share