簡體   English   中英

使用C#中的BitmapData和指針快速修改位圖

[英]Fast Bitmap modifying using BitmapData and pointers in C#

我正在從某些相機(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);
}

我正在為每個傳入的幀執行此操作。 它可以正常工作,但對於320x240像素,每幀仍需要30毫秒左右的時間。

是否可以使其更快? 也許我只能對內存中的數據進行一次鎖定/解鎖,但是對此我不確定。

不必為每個像素計算x和y,而是可以使它們成為循環計數器,如下所示:

for( y = 0;  y < bmp.Height;  y++ )
    for( x = 0;  x < bmp.Width;  x++ )

更好的是,將x和y放在一起,只是繼續增加ptr指針,而不是每個像素ptr計算ptr指針的偏移量3次。

試試這個(警告:我還沒有檢查過。)

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);
}

嘗試並行運行代碼:更改

for (int i = 0; i < data.Length; i++) {
  ...
}

進入

  Parallel.For(0, 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;
    }
  });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM