[英]How to convert Bitmap to byte[,,] faster?
我寫了函數:
public static byte[, ,] Bitmap2Byte(Bitmap image)
{
int h = image.Height;
int w = image.Width;
byte[, ,] result= new byte[w, h, 3];
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
Color c= image.GetPixel(i, j);
result[i, j, 0] = c.R;
result[i, j, 1] = c.G;
result[i, j, 2] = c.B;
}
}
return result;
}
但轉換1800x1800圖像需要將近6秒鍾。 我能更快地做到嗎?
編輯:
好的,我發現了這個: http : //msdn.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.aspx
有很好的例子。 我唯一的問題是關於Marshal.Copy
。 我可以將數據直接復制到byte[,,]
嗎?
編輯2: 好的,有時我得到奇怪的像素值,它們似乎沒有遵循r0 g0 b0 r1 g1 b1規則。 為什么? 沒關系。 弄清楚了。
編輯3:做到了。 0,13s vs 5,35s :)
通過使用從Bitmap.LockBits
返回的BitmapData
對象,可以大大提高速度。 Google“C#Bitmap LockBits”提供了大量示例。
GetPixel
令人痛苦,痛苦地緩慢,使它(具有諷刺意味)完全不適合操縱單個像素。
我一直在想這個問題。
在.NET 4.0中,Microsoft引入了並行庫。 基本上它的作用是有一個Parallel.For方法,它會自動產生許多線程來幫助完成工作。 例如,如果你最初有一個For(int i = 0; i <3; i ++){code ...},一個parallel.For循環可能會創建3個線程,每個線程將有一個不同的值,我穿過內碼。 所以我能建議的最好的東西是一個帶有一個的Parallel.For循環
Color c
lock(obraz)
{
c = obraz.GetPixel(..)
}
...
獲得像素時
如果你需要更多關於並行性的解釋,在你花一些時間研究它之前我無法真正幫助你,因為它是一個巨大的研究領域。
我剛試過並行For
。
如果沒有位圖上的SyncLock
,它就無法工作。
它說對象正在使用中。
所以它幾乎只是工作,連續大聲笑......真是一團糟。
For xx As Integer = 0 To 319
pq.ForAll(Sub(yy)
Dim Depth = getDepthValue(Image, xx, yy) / 2047
Dim NewColor = Depth * 128
Dim Pixel = Color.FromArgb(NewColor, NewColor, NewColor)
SyncLock Bmp2
Bmp2.SetPixel(xx, yy, Pixel)
End SyncLock
End Sub)
Next
如果你想知道,這是轉換kinect的depth map -> bitmap
。
Kinect的深度范圍是11位(0-2047),表示距離而不是顏色。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.