使用BitmapData和C#中的指针进行快速位图修改

Maj*_*jak 1 c# performance lockbits bitmapdata

我正从一些相机(RAW数据阵列)捕获数据.

然后我根据调色板将这些数据映射到RGB值.

我需要尽可能快地映射它,所以我使用BitmapDdata指针在不安全的代码片段中使用和编辑像素.

public void dataAcquired(int[] data)
{
    Bitmap bmp = new Bitmap(width, height); 
    BitmapData data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

    for (int i = 0; i < data.Length; i++)
    {
        int x = i % bmp.Width;
        int y = i / bmp.Width;
        Rgb rgb = mapColors[data[i]];

        unsafe
        {
            byte* ptr = (byte*)data.Scan0;
            ptr[(x * 3) + y * data.Stride] = rgb.b;
            ptr[(x * 3) + y * data.Stride + 1] = rgb.g;
            ptr[(x * 3) + y * data.Stride + 2] = rgb.r;
        }
    }
    bmp.UnlockBits(data);
}
Run Code Online (Sandbox Code Playgroud)

我正在为每个传入的帧做这个.它工作正常,但对于320x240像素,每帧仍需要30ms.

是否有可能使它更快?也许我只能在内存中锁定/解锁数据一次,但我不确定这一点.

Mik*_*kis 5

您可以将它们设置为循环计数器,而不是为每个像素计算x和y,如下所示:

for( y = 0;  y < bmp.Height;  y++ )
    for( x = 0;  x < bmp.Width;  x++ )
Run Code Online (Sandbox Code Playgroud)

更好的是,完全抛弃x和y并继续增加ptr指针而不是ptr每个像素重新计算指针偏移三次.

试试这个(警告:我没有检查过.)

public void dataAcquired()
{
    Bitmap bmp = new Bitmap(width, height); 
    BitmapData data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    unsafe
    {
        int i = 0;
        byte* ptr = (byte*)data.Scan0;
        for( int y = 0;  y < bmp.Height;  y++ )
        {
            byte* ptr2 = ptr;
            for( int x = 0;  x < bmp.Width;  x++ )
            {
                Rgb rgb = mapColors[data[i++]];
                *(ptr2++) = rgb.b;
                *(ptr2++) = rgb.g;
                *(ptr2++) = rgb.r;
            }
            ptr += data.Stride;
        }
    }
    bmp.UnlockBits(data);
}
Run Code Online (Sandbox Code Playgroud)