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];

      

+3


source to share


2 answers


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.

+3


source


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.

+2


source







All Articles