[英]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.